实现此目的的一种方法如下:
- 对于
a_contains_b,使用Series.str.contains 和一个由B 列中的值列表组成的字符串,joined 和| 分隔符来创建替代项(例如:'animal|count|cata|rownumbers|counters|inner|time|strong|kind|membrane')。
- 对于
b_contains_a,我们希望使用Series.str.extractall,因为我们需要将结果反馈给Series.isin,以了解A 列中的哪些行已匹配。 IE。 extractall (+ [0].tolist()) 的结果将是 ['ani', 'counter'],我们将其用作 df.A.isin 的输入。
- 最后,我们使用两个布尔系列作为新列的输入。使用
|,因为如果任一系列包含True,我们需要True。将结果括在括号中并应用 Series.where 结合 Series.notna 以覆盖行中的所有 False 值,而列 NaN 中的值是 A。
import pandas as pd
import numpy as np
data = {'A': {0: 'catastrop', 1: 'ani', 2: 'rows', 3: 'Second', 4: 'counter',
5: 'column', 6: np.nan, 7: np.nan, 8: np.nan, 9: np.nan},
'B': {0: 'animal', 1: 'count', 2: 'cata', 3: 'rownumbers',
4: 'counters', 5: 'inner', 6: 'time', 7: 'strong', 8: 'kind',
9: 'membrane'},
'C': {0: True, 1: True, 2: False, 3: False, 4: True, 5: False,
6: np.nan, 7: np.nan, 8: np.nan, 9: np.nan}}
df = pd.DataFrame(data)
a_contains_b = df.A.str.contains('|'.join(df.B.dropna().tolist()))
b_contains_a = df.A.isin(df.B.str.extractall(
'('+'|'.join(df.A.dropna().tolist()) + ')')[0].tolist())
df['D'] = (b_contains_a | a_contains_b).where(df.A.notna())
print(df)
A B C D
0 catastrop animal True True
1 ani count True True
2 rows cata False False
3 Second rownumbers False False
4 counter counters True True
5 column inner False False
6 NaN time NaN NaN
7 NaN strong NaN NaN
8 NaN kind NaN NaN
9 NaN membrane NaN NaN
注:如果您希望匹配不区分大小写,请考虑使用Series.str.lower。对于str.contains,您也可以使用参数case,并将其设置为False。