【问题标题】:Python. Extract last digit of a string from a Pandas columnPython。从 Pandas 列中提取字符串的最后一位
【发布时间】:2019-03-21 20:33:07
【问题描述】:

我想将“UserId”的最后一位数字存储在一个新变量中(这样的 UserId 是字符串类型)。

我想出了这个,但它是一个很长的 df 并且需要永远。关于如何优化/避免 for 循环的任何提示?

df['LastDigit'] = np.nan
for i in range(0,len(df['UserId'])):
    df.loc[i]['LastDigit'] = df.loc[i]['UserId'].strip()[-1]

【问题讨论】:

  • df['LastDigit'] = df['UserId'].str[-1] ?

标签: python python-3.x pandas


【解决方案1】:

str.stripstr[-1] 索引一起使用:

df['LastDigit'] = df['UserId'].str.strip().str[-1]

如果性能很重要并且没有缺失值,则使用列表推导:

df['LastDigit'] = [x.strip()[-1] for x in df['UserId']]

你的解决方案真的很慢,这是this的最后一个解决方案:

6) 更新一个空帧(例如使用 loc 一次一行)

性能

np.random.seed(456)
users = ['joe','jan ','ben','rick ','clare','mary','tom']
df = pd.DataFrame({
         'UserId': np.random.choice(users, size=1000),

})

In [139]: %%timeit
     ...: df['LastDigit'] = np.nan
     ...: for i in range(0,len(df['UserId'])):
     ...:     df.loc[i]['LastDigit'] = df.loc[i]['UserId'].strip()[-1]
     ...: 
__main__:3: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
57.9 s ± 1.48 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [140]: %timeit df['LastDigit'] = df['UserId'].str.strip().str[-1]
1.38 ms ± 150 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [141]: %timeit df['LastDigit'] = [x.strip()[-1] for x in df['UserId']]
343 µs ± 8.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

【讨论】:

  • 我确实喜欢 Jeff 那里的帖子(并且很好地链接了它!),但我很惊讶他从未在混合中的某个地方提到列表推导(或 np.vectorize)。是的,它们都是循环,但大多数替代方案也是如此。
【解决方案2】:

另一个选项是使用 apply。不像列表理解那样高效,但根据您的目标非常灵活。这里对形状为 (44289, 31) 的随机数据框进行了一些尝试

%timeit df['LastDigit'] = df['UserId'].apply(lambda x: str(x)[-1]) #if some variables are not strings
12.4 ms ± 215 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df['LastDigit'] = df['UserId'].str.strip().str[-1]
31.5 ms ± 688 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df['LastDigit'] = [str(x).strip()[-1] for x in df['UserId']]
9.7 ms ± 119 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

【讨论】:

    猜你喜欢
    • 2022-09-24
    • 1970-01-01
    • 2020-07-10
    • 2022-01-03
    • 2019-01-12
    • 2021-05-26
    • 2013-07-28
    • 2021-02-09
    • 2022-11-24
    相关资源
    最近更新 更多