Pandas:判断一列中的字符串是否是另一列中字符串的子串

Pandas: Determine if a string in one column is a substring of a string in another column

考虑这些系列:

>>> a = pd.Series('abc a abc c'.split())
>>> b = pd.Series('a abc abc a'.split())
>>> pd.concat((a, b), axis=1)
     0    1
0  abc    a
1    a  abc
2  abc  abc
3    c    a

>>> unknown_operation(a, b)
0 False
1 True
2 True
3 False

所需的逻辑是确定左列中的字符串是否是右列中字符串的子字符串。 pd.Series.str.contains不接受另一个系列,pd.Series.isin检查该值是否存在于另一个系列中(具体不在同一行)。我很想知道是否有矢量化解决方案(不使用 .apply 或循环),但可能没有。

IIUC,

df[1].str.split('', expand=True).eq(df[0], axis=0).any(axis=1) | df[1].eq(df[0])

输出:

0    False
1     True
2     True
3    False
dtype: bool

让我们尝试使用矢量化的 numpy defchararray

from numpy.core.defchararray import find
find(df['1'].values.astype(str),df['0'].values.astype(str))!=-1
Out[740]: array([False,  True,  True, False])

我使用随机生成的包含 1,000,000 个 5 个字母条目的 Dataframe 测试了各种功能。

运行 在我的机器上,3 次测试的平均值显示:

zip > v_find > to_list > 任意 > 应用

0.21s > 0.79s > 1s > 3.55s > 8.6s

因此,我建议使用 zip:

[x[0] in x[1] for x in zip(df['A'], df['B'])]

或矢量化查找(由 BENY 提出)

np.char.find(df['B'].values.astype(str), df['A'].values.astype(str)) != -1

我的测试设置:

    def generate_string(length):
return ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))

A = [generate_string(5) for x in range(n)]
B = [generate_string(5) for y in range(n)]
df = pd.DataFrame({"A": A, "B": B})

to_list = pd.Series([a in b for a, b in df[['A', 'B']].values.tolist()])

apply = df.apply(lambda s: s["A"] in s["B"], axis=1)

v_find = np.char.find(df['B'].values.astype(str), df['A'].values.astype(str)) != -1

any = df["B"].str.split('', expand=True).eq(df["A"], axis=0).any(axis=1) | df["B"].eq(df["A"])

zip = [x[0] in x[1] for x in zip(df['A'], df['B'])]