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

问题描述 投票:2回答:3

考虑两个数据帧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. NaNs出现在df_a值应该是的地方。

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

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

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

python python-3.x pandas merge updates
3个回答
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的细微差别。


2
投票

阅读pandas join和博客herehere应该会帮助你。

来自博客:

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

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

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
© www.soinside.com 2019 - 2024. All rights reserved.