pandas:更新和合并数据帧的更好方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pandas:更新和合并数据帧的更好方法相关的知识,希望对你有一定的参考价值。
考虑两个数据帧df_a
和df_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.concat
,pd.merge
和pd.update
的方法,但我的努力导致了一个或多个这些不良后果:
- 它破坏了
df_a
的索引(即值没有相同的索引 - 某种索引创建发生在'引擎盖下')。 - 列重命名。
- NaNs出现在
df_a
值应该是的地方。
基本上,我想要执行的操作是:
- 使用
df_a
值更新df_b
。 - 如果
df_b
中存在没有相应索引/列的值,请相应地展开df_a
以包含这些值(使索引/列保持适当的顺序)。
编辑:提供了不自然排序的更好的示例。
答案
我可以想到两种直截了当的方式来获得你的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的细微差别。
另一答案
阅读pandas join和博客here和here应该会帮助你。
来自博客:
“左外连接从表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
另一答案
这是一种方式:
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
以上是关于pandas:更新和合并数据帧的更好方法的主要内容,如果未能解决你的问题,请参考以下文章