假设我有2个pandas数据帧。
In [3]: df1 = pd.DataFrame({'id':[None,20,None,40,50],'value':[1,2,3,4,5]})
In [4]: df2 = pd.DataFrame({'index':[None,20,None], 'value':[1,2,3]})
In [7]: df1
Out[7]: id value
0 NaN 1
1 20.0 2
2 NaN 3
3 40.0 4
4 50.0 5
In [8]: df2
Out[8]: index value
0 NaN 1
1 20.0 2
2 NaN 3
当我合并这些数据帧时(基于id和index列) - 结果包括id和index缺少值的行。
df3 = df1.merge(df2, left_on='id', right_on = 'index', how='inner')
In [9]: df3
Out[9]: id value_x index value_y
0 NaN 1 NaN 1
1 NaN 1 NaN 3
2 NaN 3 NaN 1
3 NaN 3 NaN 3
4 20.0 2 20.0 2
这就是我的尝试,但我想这不是最好的解决方案:
我在一个数据帧列中用一些值替换了所有缺少的值, 和第二个数据框中的相同,但有另一个值 - 目的是条件将返回False,行将不在结果中。
In [14]: df1_fill = df1.fillna({'id':'NONE1'})
In [13]: df2_fill = df2.fillna({'index':'NONE2'})
In [15]: df1_fill
Out[15]: id value
0 NONE1 1
1 20 2
2 NONE1 3
3 40 4
4 50 5
In [16]: df2_fill
Out[16]: index value
0 NONE2 1
1 20 2
2 NONE2 3
该问题的最佳解决方案是什么?
此外,在示例中 - 连接列的日期类型是数字,但它可以是另一种类型,如文本或日期......
修改
所以,使用这里的解决方案,我可以使用dropna函数在连接之前删除缺少值的行 - 但这对于内部连接是好的,我根本不需要那些行。
左连接或完全连接怎么样?
假设我有以前用过的那两个数据帧--df1,df2。
因此,对于内部和左部连接,我真的可以使用dropna函数:
In [61]: df_inner = df1.dropna(subset=['id']).merge(df2.dropna(subset=['index']), left_on='id', right_on = 'index', how='inner')
In [62]: df_inner
Out[62]: id value_x index value_y
0 20.0 2 20.0 6
In [63]: df_left = df1.merge(df2.dropna(subset=['index']), left_on='id', right_on = 'index', how='left')
In [64]: df_left
Out[64]: id value_x index value_y
0 NaN 1 NaN NaN
1 20.0 2 20.0 6.0
2 NaN 3 NaN NaN
3 40.0 4 NaN NaN
4 50.0 5 NaN NaN
In [65]: df_full = df1.merge(df2, left_on='id', right_on = 'index', how='outer')
In [66]: df_full
Out[66]: id value_x index value_y
0 NaN 1 NaN 5.0
1 NaN 1 NaN 7.0
2 NaN 3 NaN 5.0
3 NaN 3 NaN 7.0
4 20.0 2 20.0 6.0
5 40.0 4 NaN NaN
6 50.0 5 NaN NaN
在左边,我从“右”数据框中删除了缺失值行,然后我使用了合并。
没关系,因为在左连接中你知道如果条件返回false,你在右源列中有空 - 所以如果行真的存在或者jusr返回false都没关系。
但是对于完全加入 - 我需要来自两个来源的所有行......
我不能使用dropna,因为它会丢弃我需要的行,如果我不使用它 - 我得错了结果。
感谢。
答案 0 :(得分:1)
为什么不这样做:
pd.merge(df1.dropna(subset=['id']), df2.dropna(subset=['index']),
left_on='id',right_on='index', how='inner')
输出:
id value_x index value_y
0 20.0 2 20.0 2
答案 1 :(得分:1)
如果您不想要nan值,那么您可以删除nan值,即
df3 = df1.merge(df2, left_on='id', right_on = 'index', how='inner').dropna()
或
df3 = df1.dropna().merge(df2.dropna(), left_on='id', right_on = 'index', how='inner')
输出:
id value_x index value_y
0 20.0 2 20.0 2
合并后的外合并下降即。
df_full = df1.merge(df2, left_on='id', right_on = 'index', how='outer').dropna(subset = ['id'])
输出:
id value_x index value_y
4 20.0 2 20.0 2.0
5 40.0 4 NaN NaN
6 50.0 5 NaN NaN
答案 2 :(得分:0)
因为你正在做一个内心的' join,你可以做的是在合并之前删除id列为NaN的df1中的行。
df1_nonan = df1.dropna(subset = ['id'])
df3 = df1_nonan.merge(df2, left_on='id', right_on = 'index', how='inner')