Pandas Series.str.find多起始位置及多子串的高效替代方法咨询
针对Series元素按对应起始位置查找子串的实现方案
1. Pandas/Numpy原生高效实现
Pandas的Series.str.find和Numpy的np.char.find都仅支持全局统一的start参数,没有原生函数直接支持为每个元素指定不同起始位置。不过可以用更贴合Pandas风格的apply方法替代列表推导式,代码可读性更好,效率和列表推导式接近:
import pandas as pd a = pd.Series(data=['aaba', 'ababc', 'caaauuab']) starts = [0, 1, 2] # 使用apply结合行处理 result = pd.DataFrame({'text': a, 'start': starts}).apply( lambda row: row['text'].find('b', row['start']), axis=1 )
如果追求极致效率,列表推导式本身已经是Python层面字符串操作的高效写法——因为字符串查找属于逐元素的Python对象操作,无法完全向量化,所以无需刻意替换。
2. 支持多子串对应查找的实现
如果需要为每个元素指定不同的子串和起始位置,可以扩展列表推导式或apply方法:
示例:每个元素对应不同子串与起始位置
a = pd.Series(data=['aaba', 'ababc', 'caaauuab']) substrings = ['b', 'a', 'u'] starts = [0, 1, 2] # 列表推导式实现 result = [s.find(sub, pos) for s, sub, pos in zip(a.values, substrings, starts)] # Pandas apply实现 result_series = pd.DataFrame({'text': a, 'sub': substrings, 'start': starts}).apply( lambda row: row['text'].find(row['sub'], row['start']), axis=1 )
如果需要查找每个元素在对应起始位置下,多个子串的第一个匹配位置,可以自定义函数处理:
def find_first_match(text, start, substrings): for sub in substrings: pos = text.find(sub, start) if pos != -1: return pos return -1 # 示例:每个元素对应起始位置和一组子串 substrings_list = [['b', 'a'], ['a', 'c'], ['u', 'b']] result = pd.DataFrame({'text': a, 'start': starts, 'subs': substrings_list}).apply( lambda row: find_first_match(row['text'], row['start'], row['subs']), axis=1 )
内容的提问来源于stack exchange,提问作者subhacom
相关产品推荐
相关产品推荐

