使用pandas,我创建了两个类似于下面的数据框。
input_df1 = pd.DataFrame({'names':['phone,mobile,cell','boat,ship','car'], 'values':[1,3,3]})
input_df2 = pd.DataFrame({'names':['cell,phone','car,automobile', 'boat'], 'values':[3,7,1]})
我想将'names'列更改为仅包含在两个数据框中找到的名称。目标是让这些名称的值在比较图中自动组合在一起。最终的数据框应该如下所示。
如果两个数据框中都有多个名称可用,则名称不会简化为一个名称,如上面的第0行所示。应该最好删除它们之间没有通用名称的行(但我也可以事先手动完成)。优选地,这也应该在没有for循环的情况下完成,因为实际数据帧超过50k行。
我尝试使用input_df.names.str.contains()
和input_df.names.isin()
,但我无法弄清楚如何在input_df1
中找到与input_df2
中的名称匹配的名称,比较它们的最短名称,然后用较短的名称替换较长的名称(这是我的思想应该做的)。
答案 0 :(得分:0)
这是一种策略。
# your data
# =======================================
input_df1 = pd.DataFrame({'names':['phone,mobile,cell','boat,ship','car'], 'values':[1,3,3]})
input_df1
names values
0 phone,mobile,cell 1
1 boat,ship 3
2 car 3
input_df2 = pd.DataFrame({'names':['cell,phone','car,automobile', 'boat'], 'values':[3,7,1]})
input_df2
names values
0 cell,phone 3
1 car,automobile 7
2 boat 1
我们首先将平面名称记录转换为堆积名称记录。
# groupby-tostack function
# ===============================
def func(group):
return pd.Series(group['names'].values[0].split(','))
stacked_names1 = input_df1.groupby(level=0).apply(func)
stacked_names1
0 0 phone
1 mobile
2 cell
1 0 boat
1 ship
2 0 car
dtype: object
stacked_names2 = input_df2.groupby(level=0).apply(func)
stacked_names2
0 0 cell
1 phone
1 0 car
1 automobile
2 0 boat
dtype: object
接下来,使用np.intersec1d
获取常用名称。
common_names = np.intersect1d(stacked_names1, stacked_names2)
common_names
array(['boat', 'car', 'cell', 'phone'], dtype=object)
使用.isin
保留有效名称。
stacked_names1.isin(common_names)
0 0 True
1 False
2 True
1 0 True
1 False
2 0 True
dtype: bool
最后,再次通过外层索引上的groupby将堆叠记录转换回平面记录。
def func2(group):
return pd.Series(','.join(group.values.tolist()))
input_df1['names'] = stacked_names1[stacked_names1.isin(common_names)].groupby(level=0).apply(func2).values
input_df1
names values
0 phone,cell 1
1 boat 3
2 car 3
input_df2['names'] = stacked_names2[stacked_names2.isin(common_names)].groupby(level=0).apply(func2).values
input_df2
names values
0 cell,phone 3
1 car 7
2 boat 1