如果 df 中的列的值是同一数据框中另一列的值之一(逐行),则匹配

Matching if value of a column in a df is one of the values of another column in the same dataframe(going row by row)

df

col1  col2
A      a|x|y
B      a|x|y
C      c|x|z
D      e|j|y

我的objective是创建一个新的列名为'status'来查看col1中的条目是否是col2中的条目之一(用竖线分隔)。 输出应该是这样的

col1  col2     status
A      a|x|y   True
B      a|x|y   False
C      c|x|z   True
D      e|j|y   False

我的代码:

df["col1"]= df["col1"].str.lower()
df['status']=df['col1'].isin(df['col2']) 

但是这将 'status' 列中的所有条目都设为 False

请帮帮我,拜托!!!

get_dummies

df.col2.str.get_dummies().mul(pd.get_dummies(df.col1.str.lower())).sum(1).astype(bool)

0     True
1    False
2     True
3    False
dtype: bool

a = pd.get_dummies(df.col1.str.lower())
b = df.col2.str.get_dummies()
status = b.mul(a).sum(1).astype(bool)
df = df.assign(status=status)

df

  col1   col2  status
0    A  a|x|y    True
1    B  a|x|y   False
2    C  c|x|z    True
3    D  e|j|y   False

get_dummieseinsum

a = pd.get_dummies(df.col1.str.lower())
b = df.col2.str.get_dummies()
a, b = a.align(b, fill_value=0)
status = np.einsum('ij,ij->i', a, b).astype(bool)

df = df.assign(status=status)
df

  col1   col2  status
0    A  a|x|y    True
1    B  a|x|y   False
2    C  c|x|z    True
3    D  e|j|y   False

类似,您可以使用列表理解。假设您的数据是干净的,例如没有空值。

zipper = zip(df['col1'], df['col2'])
df['status'] = [i.casefold() in j.casefold().split('|') for i, j in zipper]

print(df)

  col1   col2 status
0    A  a|x|y   True
1    B  a|x|y  False
2    C  c|x|z   True
3    D  e|j|y  False

也许您应该首先将数据框转换为更易于使用的格式。

我建议这样:

>>> df = pd.concat([df['col1'], df['col2'].str.upper().str.split('|', expand=True)], axis=1)                                                                                                             
>>> df                                                                                                                                                                                                   
  col1  0  1  2
0    A  A  X  Y
1    B  A  X  Y
2    C  C  X  Z
3    D  E  J  Y

现在你可以做:

>>> df['status'] = df.apply(lambda s: s.duplicated().any(), axis=1)                                                                                                                                     
>>> df                                                                                                                                                                                                    
  col1  0  1  2  status
0    A  A  X  Y    True
1    B  A  X  Y   False
2    C  C  X  Z    True
3    D  E  J  Y   False

此解决方案假定您用 '|' 分隔的状态指示器是唯一的,即您不能有类似 'x|x|x'.

的东西

如果您不喜欢这个建议,请考虑:

>>> df['status'] = df.apply(lambda row: row[0].lower() in row[1].split('|'), axis=1)                                                                                                                     
>>> df                                                                                                                                                                                                  
   col1   col2  status
0    A  a|x|y    True
1    B  a|x|y   False
2    C  c|x|z    True
3    D  e|j|y   False