基于字符串长度的数据帧列切片

2024-05-17 15:57:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我想删除数据帧列中字符串的前3个字符,该列的字符串长度大于等于4

否则它们应该保持不变。在

例如

bloomberg_ticker_y

AIM9
DJEM9 # (should be M9)
FAM9
IXPM9 # (should be M9)

我可以按长度筛选字符串:

^{pr2}$

把绳子切成薄片:

merged['bloomberg_ticker_y'].str[-2:]

但不知道如何把它放在一起并应用到我的数据帧

任何帮助都将不胜感激。在


Tags: 数据字符串beticker薄片should个字符绳子
3条回答

您可以使用numpy.where来应用一个条件来根据字符串长度选取切片。在

np.where(df['bloomberg_ticker_y'].str.len() > 4, 
         df['bloomberg_ticker_y'].str[3:], 
         df['bloomberg_ticker_y'])
# array(['AIM9', 'M9', 'FAM9', 'M9'], dtype=object)

^{pr2}$


如果你喜欢一个基于矢量化的map的解决方案,它就是

df['bloomberg_ticker_y'].map(lambda x: x[3:] if len(x) > 4 else x)

0    AIM9
1      M9
2    FAM9
3      M9
Name: bloomberg_ticker_y, dtype: object

看到各种各样的答案,所以决定从速度上比较:

# Create big size test dataframe
df = pd.DataFrame({'bloomberg_ticker_y' : ['AIM9', 'DJEM9', 'FAM9', 'IXPM9']})
df = pd.concat([df]*100000)
df.shape

#Out
(400000, 1)

CS95 1np.where

^{pr2}$

结果:

163 ms ± 12.8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

基于CS95#2矢量化map的解决方案

%%timeit 
df['bloomberg_ticker_y'].map(lambda x: x[3:] if len(x) > 4 else x)

结果:

86 ms ± 7.31 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

雅图DataFrame.mask

%%timeit
df.bloomberg_ticker_y.mask(df.bloomberg_ticker_y.str.len().gt(4), 
                           other=df.bloomberg_ticker_y.str[-2:])

结果:

187 ms ± 18.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Vlemaistrelist comprehension

%%timeit
[x[-2:] if len(x)>4 else x for x in df['bloomberg_ticker_y']]

结果:

84.8 ms ± 4.85 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

保罗str.replaceregex

%%timeit
df["bloomberg_ticker_y"].str.replace(r".{3,}(?=.{2}$)", "")

结果:

324 ms ± 17.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

眼镜蛇

%%timeit
df.apply(lambda x: (x['bloomberg_ticker_y'][3:] if len(x['bloomberg_ticker_y']) > 4 else x['bloomberg_ticker_y']) , axis=1)

结果:

6.83 s ± 387 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

结论

  • 最快的方法是list comprehension,紧随其后的是基于map的矢量化解。

  • 到目前为止,最慢的方法是DataFrame.apply(如预期),然后是{},再加上{}

您可以使用列表理解:

df = pd.DataFrame({'bloomberg_ticker_y' : ['AIM9', 'DJEM9', 'FAM9', 'IXPM9']})

df['new'] = [x[-2:] if len(x)>4 else x for x in df['bloomberg_ticker_y']]

输出:

^{pr2}$

相关问题 更多 >