PythonPandas交叉检查列之间的子集关系

2admgd59  于 2022-10-23  发布在  Python
关注(0)|答案(1)|浏览(95)
ABC
大灾难动物真的
anicount
rowscataFalse
第二行数
counter计数器
内部
时间
种类

A和B都包含字符串和子字符串,我想检查列A是否有值“counter”,并且该值是**,要么在列B中有子字符串“count”,要么是列B中“counters”的子字符串**。如果满足任意,则返回True。(类似于.isin和.str.contains的组合)。C是输出,它表示A的值是B的子字符串还是A包含B。就像catastrop包含cata,所以True,ani是animal的子字符串,所以Tru
我最初想到的代码是

list1=a1['A'].tolist()
output1=[]
for i in list1:
    output1.append(any(a1['B'].str.contains(i,regex=False)))

并对列B执行或运算
但如果我做的相反,就像

list2=a1['B'].tolist()
output2=[]
for i in list2:
    output2.append(any(a1['A'].str.contains(i,regex=False)))

列表2将包含关于列B而不是列A的验证结果。
我该如何编写此代码?

hfyxw5xn

hfyxw5xn1#

实现这一目标的一种方法如下:

  • 对于a_contains_b,将Series.str.contains与由列Bjoined|分隔符中的值列表组成的字符串一起使用,以创建替代项(因此:'animal|count|cata|rownumbers|counters|inner|time|strong|kind|membrane')。
  • 对于b_contains_a,我们希望改用Series.str.extractall,因为我们需要将结果反馈给Series.isin以了解列A中的哪些行已匹配。一、 e.extractall(+[0].tolist())的结果将是['ani', 'counter'],我们将其用作df.A.isin的输入。
  • 最后,我们使用这两个布尔序列作为新列的输入。使用|,因为如果任何一个序列包含True的话,我们需要True。将结果用括号括起来,并应用Series.whereSeries.notna组合,覆盖列A中具有NaN值的行中的所有False数值。
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

N、 B.如果希望匹配不区分大小写,请考虑使用Series.str.lower。在str.contains的情况下,还可以使用参数case,并将其设置为False

相关问题