我的目标
我正在尝试通过比较来自不同数据帧的列来创建新的数据帧。
更具体地说,当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
中删除。在这种情况下,Egg
和rows
都不存在,因此,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 非常基本相似。
答案 0 :(得分:1)
我没有精力处理所有边缘情况。但您可能会发现此方法很有用。如果没有,不用担心。
set
和<=
来测试df
中df1
中的字符作为相似度的衡量标准。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
次检查。由于a
和b
都是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']]