我想要实现的是基于ColA组合2个数据帧,并且ColC中的值也应在各列之间匹配(即检查列表中是否存在该值)。您能否提出一种有效且简单的方法来解决此问题?我知道可以通过遍历数据帧1的行并比较值来以正常方式完成此操作。但是我觉得应该有其他好的方法(熊猫方法)来解决这个问题。
提前谢谢
答案 0 :(得分:2)
我将在此处使用unnesting。
df1['ListCol']=df1['ColC']# Here I am try to record the original data
Yourdf=unnesting(df1,['ColC']).merge(df2, on=['ColA','ColC'],how='inner')
Yourdf
ColC ColA ColB ListCol
0 2 A 1 [1, 2, 3]
1 3 A 1 [1, 2, 3]
2 6 A 2 [4, 5, 6]
3 2 B 4 [1, 2, 3]
4 5 B 5 [3, 4, 5]
def unnesting(df, explode):
idx = df.index.repeat(df[explode[0]].str.len())
df1 = pd.concat([
pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
df1.index = idx
return df1.join(df.drop(explode, 1), how='left')
答案 1 :(得分:2)
您可以这样操作,在数据框1中扩展ColC,即df1,然后将ColA上的合并和df1中的“ melted”列融为一列:
df1 = pd.DataFrame({'ColA':[*'AABBB'],
'ColB':[1,2,3,4,5],
'ColC':[[1,2,3],[4,5,6],[7,8,9],[1,2,3],[3,4,5]]})
df2 = pd.DataFrame({'ColA':[*'AAABB'], 'ColC':[3,6,2,2,5]})
df1_m = df1.assign(**pd.DataFrame([i for i in df1['ColC'].values]).add_prefix('ColC_'))\
.melt(['ColA','ColB','ColC'])
df_out = df2.merge(df1_m, left_on=['ColA','ColC'], right_on=['ColA','value'])
df_out
输出:
ColA ColC_x ColB ColC_y variable value
0 A 3 1 [1, 2, 3] ColC_2 3
1 A 6 2 [4, 5, 6] ColC_2 6
2 A 2 1 [1, 2, 3] ColC_1 2
3 B 2 4 [1, 2, 3] ColC_1 2
4 B 5 5 [3, 4, 5] ColC_2 5
答案 2 :(得分:1)
另一种方法是将merge
上的ColA
和apply
与python in
运算符一起使用,以仅选择ColC_y
位于ColC_x
中的行< / p>
In [19]: df1
Out[19]:
ColA ColB ColC
0 A 1 [1, 2, 3]
1 A 2 [4, 5, 6]
2 B 3 [7, 8, 9]
3 B 4 [1, 2, 3]
4 B 5 [3, 4, 5]
In [20]: df2
Out[20]:
ColA ColC
0 A 3
1 A 6
2 A 2
3 B 2
4 B 5
In [21]: df3 = df1.merge(df2, on=['ColA'])
In [22]: df3
Out[22]:
ColA ColB ColC_x ColC_y
0 A 1 [1, 2, 3] 3
1 A 1 [1, 2, 3] 6
2 A 1 [1, 2, 3] 2
3 A 2 [4, 5, 6] 3
4 A 2 [4, 5, 6] 6
5 A 2 [4, 5, 6] 2
6 B 3 [7, 8, 9] 2
7 B 3 [7, 8, 9] 5
8 B 4 [1, 2, 3] 2
9 B 4 [1, 2, 3] 5
10 B 5 [3, 4, 5] 2
11 B 5 [3, 4, 5] 5
In [23]: df3[df3.apply(lambda x: x['ColC_y'] in x['ColC_x'], axis=1)]
Out[23]:
ColA ColB ColC_x ColC_y
0 A 1 [1, 2, 3] 3
2 A 1 [1, 2, 3] 2
4 A 2 [4, 5, 6] 6
8 B 4 [1, 2, 3] 2
11 B 5 [3, 4, 5] 5