当数据框B中的列值不相似时,从数据框A中删除行

时间:2017-01-01 21:53:36

标签: python python-2.7 pandas dataframe

我的目标

我正在尝试通过比较来自不同数据帧的列来创建新的数据帧。

更具体地说,当ColumnA中的ColumnB列值与new_df中的列值不相同时, 整行被忽略且未包含在>>> df ColumnA Stats 0 Cake 872 1 Cheese Cake 912 2 Egg 62 3 Raspb Jam 091 4 Bacon 123 5 Bread 425 >>> df1 ColumnB 0 Cake 1 Cheese Cake 3 Raspberry Jam 4 Bacon

数据框

new_df = df[df['ColumnA'].str.strip() in df1['ColumnB'].str.split()]

我的尝试

由于我不确定如何实现这一点,我已尽力制作以下内容,但我知道它可能无法实现我的预期输出:

TypeError: 'Series' objects are mutable, thus they cannot be hashed

错误:

df1

预期输出

如您所见,对于df中不存在的列值,行将从Bread中删除。在这种情况下,Eggrows都不存在,因此,new_df不包含其>>> new_df ColumnA Stats 0 Cake 872 1 Cheese Cake 912 3 Raspberry Jam 091 4 Bacon 123

Raspb Jam

修改

{{1}} 也会保留在新的DF中,因为它与Raspberry Jam 非常基本相似。

2 个答案:

答案 0 :(得分:1)

我没有精力处理所有边缘情况。但您可能会发现此方法很有用。如果没有,不用担心。

  • 使用set<=来测试dfdf1中的字符作为相似度的衡量标准。
  • 利用numpy的广播来提供帮助
a = df.ColumnA.apply(set).values
b = df1.ColumnB.apply(set).values

print(df[(a[:, None] <= b).any(1)])

       ColumnA  Stats
0         Cake    872
1  Cheese Cake    912
3    Raspb Jam     91
4        Bacon    123

对评论的回复

您可以使用

强制列为str
a = df.ColumnA.astype(str).apply(set).values
b = df1.ColumnB.astype(str)..apply(set).values

解释

  • a[:, None]将单维a数组重新整形为二维数组。这使我能够进行numpy broadacasting
  • set个对象使用<=执行issubset次检查。由于ab都是set,我们a[:, None] <= b]执行a[i]的所有成对比较b[j]我,j。
  • (a[:, None] <= b).any(1)检查a[i]是否为b[j]的任何j的子集。我在b中找到至少一个a[i]是<。li}的子集的元素。

答案 1 :(得分:1)

您可以使用map函数提供显式查找。

df = DataFrame( {'ColumnA' : ['Cake' ,'Cheese Cake','Egg' , 'Raspb Jam' ,'Bacon' ,'Bread'],'Value' : [872,912,62,91,123, 425]})
df1 = DataFrame(['Cake' ,'Cheese Cake','Raspberry Jam','Bacon'],columns=['ColumnB'])
value_map = {'Raspberry Jam' : 'Raspb Jam' }
df1.ColumnB = df1.ColumnB.map(lambda x : value_map.get(x,x))
df1.rename(columns={'ColumnB' : 'ColumnA'},inplace=True)
df.merge(df1)
   ColumnA  Value
0         Cake    872
1  Cheese Cake    912
2    Raspb Jam     91
3        Bacon    123

或者,使用left_on和right_on param指定要合并的列名。

df.merge(df1,how='inner',left_on='ColumnA',right_on='ColumnB')[['ColumnA','Value']]