python - pandas 高效合并和更新
问题描述
我正在从数据库中获取 df1。df2 需要与 df1 合并。Df1 包含 df2 中不存在的其他列。df2 包含 df1 中已经存在的索引以及需要更新哪些行。数据框是多索引的。
我想要什么: - 保留 df1 中不在 df2 中的行 - 使用 df2 的值更新 df1 的值以匹配索引 - 在更新的行中保留 df2 中不存在的列的值。-追加在 df2 但不在 df1 中的行
我的解决方案:
import pandas as pd
import numpy as np
df1 = pd.DataFrame(
data={'idx1': ['A', 'B', 'C', 'D', 'E'], 'idx2': [1, 2, 3, 4, 5], 'one': ['df1', 'df1', 'df1', 'df1', 'df1'],
'two': ["y", "x", "y", "x", "y"]})
df2 = pd.DataFrame(data={'idx1': ['D', 'E', 'F', 'G'], 'idx2': [4, 5, 6, 7], 'one': ['df2', 'df2', 'df2', 'df2']})
desired_result = pd.DataFrame(data={'idx1': ['A', 'B', 'C', 'D', 'E', 'F', 'G'], 'idx2': [1, 2, 3, 4, 5, 6, 7],
'one': ['df1','df1','df1','df2', 'df2', 'df2', 'df2'], 'two': ["y", "x", "y", "x", "y",np.nan,np.nan]})
updated = pd.merge(df1[['idx1', 'idx2']], df2, on=['idx1', 'idx2'], how='right')
keep = df1[~df1.isin(df2)].dropna()
my_res = pd.concat([updated, keep])
my_res.drop(columns='two', inplace=True)
my_res = pd.merge(my_res,df1[['idx1','idx2','two']], on=['idx1','idx2'])
这是非常低效的,因为我:
通过右外连接 df2 合并到 df1 的仅索引列
查找在 df2 但不在 df1 中的索引
连接两个数据框
删除未包含在 df2 中的列
合并索引以附加我之前删除的那些列
有没有更有效更简单的方法来做到这一点?我只是无法解决这个问题。
编辑:通过 mutliindexed 我的意思是要识别一行我需要查看 4 个不同的列组合。不幸的是,我的解决方案无法正常工作。
解决方案
使用DataFrame.append
,Dataframe.drop_duplicates
和Series.update
:
首先我们附加 df1 和 df2。然后我们根据列idx1
和删除重复项idx2
。最后,我们根据 df1 中的现有值更新该two
列。NaN
df3 = (df1.append(df2, sort=False)
.drop_duplicates(subset=['idx1', 'idx2'], keep='last')
.reset_index(drop=True))
df3['two'].update(df1['two'])
idx1 idx2 one two
0 A 1 df1 y
1 B 2 df1 x
2 C 3 df1 y
3 D 4 df2 x
4 E 5 df2 y
5 F 6 df2 NaN
6 G 7 df2 NaN
推荐阅读
- javascript - 输入字段未更新数组中的“地址”
- vue.js - 如何向 vue 中的 getter 发送参数?
- javascript - 禁用 Angular 2 多选复选框
- c - 单次使用后在宏内部取消定义常量
- javascript - 将 javascript 对象键更改为属性值
- amazon-cloudfront - 如何在 AWS 中部署受 OpenId Connect 保护的网站?
- c - 命令行参数值检查和退出代码
- verilog - Verilog:条件分支
- python - 提高 np.fromfuction 的性能
- jpa - 如何使用自动生成的主键(也是另一个表的外键)使用 JPA 插入数据?