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

时间:2018-02-13 23:04:35

标签: 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值的位置。
  4. 基本上,我想要执行的操作是:

    1. 使用df_a
    2. 的值更新df_b
    3. 如果df_b中存在没有相应索引/列的值,请相应地展开df_a以包含这些值(使索引/列保持适当的顺序)。
    4. 编辑:提供非自然排序的更好示例。

3 个答案:

答案 0 :(得分:3)

我可以想到两种直截了当的方法来获取你的df_e;不过,我不会考虑列顺序。将额外的第4列添加到df_b,只是为了显示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

注意对齐引入的dtype的细微差别。

答案 1 :(得分:2)

通过大熊猫join和博客here以及here阅读应该会对您有所帮助。

来自博客:

  

“左外连接从表A中生成一组完整的记录,表B中有匹配的记录(如果可用)。如果没有匹配,则右侧将包含null。”

df_b.join(df_a, how='left', lsuffix='_b').drop('2', axis=1).rename(columns={'2_b': 2})

    2   1   3
0   d   1.0 4.0
1   e   2.0 5.0
2   f   NaN NaN
3   g   3.0 6.0

答案 2 :(得分:0)

这是一种方式:

df_b[[1, 3]] = df_a[[1, 3]]

结果:

print(df_b)

   2    1    3
0  d  1.0  4.0
1  e  2.0  5.0
2  f  NaN  NaN
3  g  3.0  6.0