蟒蛇。从Pandas列中提取字符串的最后一个字母

时间:2018-10-17 08:13:07

标签: python python-3.x pandas

我想将'UserId'的最后一位存储在新变量中(此类UserId的类型为字符串)。

我想出了这个,但这是一个漫长的df,并且要花很长时间。关于如何优化/避免循环的任何提示?

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

2 个答案:

答案 0 :(得分:2)

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)

答案 1 :(得分:1)

另一个选择是使用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)

希望这会有所帮助