pandas :更新和合并数据帧的更好方式

2022-04-16 00:00:00 python python-3.x pandas merge updates

问题描述

考虑两个数据帧df_adf_b

>>> df_a = pd.DataFrame.from_dict({1: [1,2,3], 2: ["a", "b", "c"], 3:[4,5,6]})
>>> df_a.index = pd.Index([0,1,3])
>>> print(df_a)

   1  2  3
0  1  a  4
1  2  b  5
3  3  c  6

>>> df_b = pd.DataFrame.from_dict({2: ["d", "e", "f", "g"]})
>>> print(df_b)

   2
0  d
1  e
2  f
3  g

和以下代码:

>>> df_a = pd.concat([df_a, df_b])
>>> df_c = df_a.loc[~df_a.index.duplicated(keep='last'),df_b.columns]
>>> df_d = df_a.loc[~df_a.index.duplicated(keep='first'), ~df_a.columns.isin(df_b.columns)]
>>> df_e = df_d.merge(df_c, "outer", left_index=True, right_index=True)
>>> df_e.sort_index(axis=1, inplace=True)

生成所需的数据帧(df_e):

>>> print(df_e)
     1  2    3
0  1.0  d  4.0
1  2.0  e  5.0
2  NaN  f  NaN
3  3.0  g  6.0

是否有更有效的方法到达df_e?我尝试了使用pd.concatpd.mergepd.update的各种方法,但我的努力导致了以下一个或多个不良后果:

  1. 它会中断df_a的索引(即这些值不具有相同的索引--某种索引创建是在幕后进行的)。
  2. 列已重命名。
  3. NaN出现在df_a值应该出现的位置。

基本上,我要执行的操作是:

  1. 使用df_b的值更新df_a
  2. 如果df_b中存在没有相应索引/列的值,请适当展开df_a以包括这些值(保持索引/列的适当顺序)。

编辑:提供了不会自然排序的更好的示例。


解决方案

我可以想出两种简单的方法来获得您的df_e;不过,我不会过多地考虑列顺序。向df_b添加额外的第4列,只是为了显示df_a中不存在的列的行为:

In [63]: m = df_b.combine_first(df_a)

In [64]: m
Out[64]: 
     1  2    3   4
0  1.0  d  4.0  10
1  2.0  e  5.0  11
2  NaN  f  NaN  12
3  3.0  g  6.0  13

In [65]: a,b = df_a.align(df_b)

In [66]: a.update(b)

In [67]: a
Out[67]: 
     1  2    3     4
0  1.0  d  4.0  10.0
1  2.0  e  5.0  11.0
2  NaN  f  NaN  12.0
3  3.0  g  6.0  13.0

请注意对齐引入的数据类型略有不同。

相关文章