我已经检查了关于stackoverflow的几篇文章,但是没有发现类似的内容。
我有以下数据框:
df1 = pd.DataFrame({'col1': ['A','M','C'],
'col2': ['B','N','O'],
# plus many more
})
df2 = pd.DataFrame({'col3': ['A','A','A','B','B','B'],
'col4': ['M','P','Q','J','P','M'],
# plus many more
})
看起来像这样:
df1:
col1 col2
A B
M N
C O
...plus many more
df2:
col3 col4
A M
A P
A Q
B J
B P
B M
...plus many more
目标是为col4
中一行中出现的每个col3
创建一个包含df1
中所有元素的数据框。例如,让我们看一下df1
的第1行。我们看到A
在col1
中,而B
在col2
中。然后,我们转到df2
,并检查col4
和df2[df2['col3'] == 'A']
的{{1}}是什么。对于df2[df2['col3'] == 'B']
:A
,对于['M','P','Q']
,我们得到B
。它们的交集是['J','P','M']
,所以我想要的是这样的
['M', 'P']
处理此问题的幼稚方法是遍历行然后获取交集,但是我想知道是否有可能通过合并技术或其他更快的方法来解决这个问题。到目前为止,我还没想到怎么做。
答案 0 :(得分:1)
使用merge
,groupby
和设置交集的组合,应该可以实现您想要的目标:
# Getting tuple of all col1=col3 values in col4
df3 = pd.merge(df1, df2, left_on='col1', right_on='col3')
df3 = df3.groupby(['col1', 'col2'])['col4'].apply(tuple)
df3 = df3.reset_index()
# Getting tuple of all col2=col3 values in col4
df3 = pd.merge(df3, df2, left_on='col2', right_on='col3')
df3 = df3.groupby(['col1', 'col2', 'col4_x'])['col4_y'].apply(tuple)
df3 = df3.reset_index()
# Taking set intersection of our two tuples
df3['col4'] = df3.apply(lambda row: set(row['col4_x']) & set(row['col4_y']), axis=1)
# Dropping unnecessary columns
df3 = df3.drop(['col4_x', 'col4_y'], axis=1)
print(df3)
col1 col2 col4
0 A B {P, M}
如果需要,请参见this answer,了解如何“融化” col4
的示例。