匹配df中某列的值是否是同一数据帧中另一列的值之一(逐行)

时间:2018-11-30 12:41:06

标签: python string pandas matching

df

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

我的目标是创建一个名为“状态”的新列,以查看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']) 

但这会将“状态”列中的所有条目都设为False

请帮助我!!!

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

类似于this answer,您可以使用列表推导。假设您的数据是干净的,例如没有空值。

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

答案 2 :(得分:2)

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

我建议这样:

>>> 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