多个数据框中,如何高效地合并具有互补缺失值的数据?

3
这可能是一个比较基础的问题。假设我有两个数据框:
>>> df1
   id     a
0   0   5.0
1   1  10.0
2   2  15.0
3   3   NaN
4   4   NaN
5   5   NaN

>>> df2
   id     a
0   0   NaN
1   1   NaN
2   2   NaN
3   3  20.0
4   4  25.0
5   5  30.0



我想将数据框按照id进行连接,使其看起来像这样:
>>> df_joined
   id     a
0   0   5.0
1   1  10.0
2   2  15.0
3   3  20.0
4   4  25.0
5   5  30.0

到目前为止,我一直在进行左连接合并,例如df1.merge(df2, how = 'left', on = 'id) 。但这会导致重复的列(如下所示),需要通过填充NaN值,重命名列名,最后删除重复列来进行矫正。如果我要合并超过两个数据框架,这将变得特别繁琐。

# How do I better merge this so I don't have fill nans, rename, and drop the columns?
   id   a_x   a_y
0   0   5.0   NaN
1   1  10.0   NaN
2   2  15.0   NaN
3   3   NaN  20.0
4   4   NaN  25.0
5   5   NaN  30.0

有没有更好的方法来完成这个任务?

1个回答

4

如果我理解正确,DataFrame.combine_first

df1.combine_first(df2)

   id     a
0   0   5.0
1   1  10.0
2   2  15.0
3   3  20.0
4   4  25.0
5   5  30.0

编辑

我们可以使用DataFrame.set_index + DataFrame.combine_first,结合mapreduce来处理n个数据框。

my_list_df = [df1, df2]

from functools import reduce
reduce(lambda new_df,  df_to_combine: new_df.combine_first(df_to_combine), 
       map(lambda df: df.set_index('id'), my_list_df)).reset_index()

输出

   id     a
0   0   5.0
1   1  10.0
2   2  15.0
3   3  20.0
4   4  25.0
5   5  30.0

在这种情况下,我们只需要使用reduce:
reduce(lambda new_df, df_to_combine: new_df.combine_first(df_to_combine.set_index('id')),
       my_list_df[1:], my_list_df[0].set_index('id')).reset_index()

1
我认为combine_first是基于位置的,但OP谈到了基于列id来填充列a,在这里它起作用是因为id列和索引相同,并且两个数据框以相同的方式排序。 - Ben.T
1
感谢@Ben.T - 说得好。让我澄清一下,我们可以假设所有数据框的顺序都相同。在这种情况下,看起来combine_first即使id与索引不同也可以工作。如果它们的顺序不同,则无法工作。 - jetvermillion
@jetvermillion 如果它们以相同的顺序和相同的索引排序,那么combine_first是一个很好的解决方案。 - Ben.T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接