结合使用str.rsplit 和str.get 以获得您想要的结果。 str.rsplit 只是从末尾拆分字符串,而 str.get 获取 pd.Series 对象中迭代器的第 n 个元素。
回答
d6['SOURCE_NAME'] = df['SOURCE_NAME'].str.rsplit('_', n=1).str.get(0)
rsplit 中的 n 参数限制了输出中的拆分次数,因此您只保留最后一个“_”之前的所有内容。
尽管使用pd.Series.apply 的解决方案几乎快了一半,但我喜欢这个解决方案,因为它的语法更具表现力。如果你想使用pd.Series.apply解决方案(更快)检查计时部分!
pandas documentation.
示例
strs = ['Stackoverflow_1234',
'Stack_Over_Flow_1234',
'Stackoverflow',
'Stack_Overflow_1234']
df = pd.DataFrame(data={'SOURCE_NAME': strs})
这会导致
print(df)
SOURCE_NAME
0 Stackoverflow_1234
1 Stack_Over_Flow_1234
2 Stackoverflow
3 Stack_Overflow_1234
使用建议的解决方案:
df['SOURCE_NAME'].str.rsplit('_', 1).str.get(0)
0 Stackoverflow
1 Stack_Over_Flow
2 Stackoverflow
3 Stack_Overflow
Name: SOURCE_NAME, dtype: object
时间
有趣的是,使用pd.Series.str 不一定比使用pd.Series.apply 快:
import pandas as pd
df = pd.DataFrame(data={'SOURCE_NAME': ['stackoverflow_1234_abcd'] * 1000})
%timeit df['SOURCE_NAME'].apply(lambda x: x.rsplit('_', 1)[0])
497 µs ± 30.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit df['SOURCE_NAME'].str.rsplit('_', n=1).str.get(0)
1.04 ms ± 4.27 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# increasing the number of rows x 100
df = pd.concat([df] * 100)
%timeit df['SOURCE_NAME'].apply(lambda x: x.rsplit('_', 1)[0])
31.7 ms ± 1.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df['SOURCE_NAME'].str.rsplit('_', n=1).str.get(0)
84.1 ms ± 6.88 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)