Pandas多索引DataFrame的部分索引匹配与值迁移问题
解决Pandas多索引DataFrame的匹配更新问题
问题场景
现有两个带多索引的Pandas DataFrame:
df1 定义与输出
import pandas as pd # Sample MultiIndex data1 = { 'value': [10, 20, 30, 40, 50, 60], 'level_3': ['alpha','beta','gamma','delta','kappa','omega'], 'level_1': [1, 2, 3, 4, 5, 6], 'level_2': ['A', 'B', 'C', 'D', 'E', 'F'] } df1 = pd.DataFrame(data1) df1.set_index(['level_1', 'level_2','level_3'], inplace = True) print(df1)
输出:
value level_1 level_2 level_3 1 A alpha 10 2 B beta 20 3 C gamma 30 4 D delta 40 5 E kappa 50 6 F omega 60
df2 定义与输出
data2 = { 'value': [300, 200], 'level_5': ['jersey','michigan'], 'level_2': ['A', 'B'], 'level_1': [1, 2] } df2 = pd.DataFrame(data2) df2.set_index(['level_1', 'level_2','level_5'], inplace = True) print(df2)
输出:
value level_1 level_2 level_5 1 A jersey 300 2 B michigan 200
需求
自动识别两个DataFrame的共同索引名(本例中为level_1和level_2),将df2中的value值匹配更新到df1对应的行中。最终需要将df1中(1,"A")和(2,"B")行的value分别替换为300和200。
解决方案
步骤1:自动识别共同索引名
通过集合交集操作提取两个DataFrame索引名的交集,同时保持索引名在df1中的原有顺序:
common_index_names = list(set(df1.index.names) & set(df2.index.names)) common_index_names = [name for name in df1.index.names if name in common_index_names]
步骤2:处理df2并匹配更新df1
将df2重置索引后仅保留共同索引和value列,重新设置共同索引为索引,最后用update方法将匹配到的值覆盖到df1:
# 提取df2中需要的列并重构索引 df2_filtered = df2.reset_index()[common_index_names + ['value']] df2_filtered.set_index(common_index_names, inplace=True) # 更新df1对应行的值 df1.update(df2_filtered)
完整代码与验证
import pandas as pd # 定义df1 data1 = { 'value': [10, 20, 30, 40, 50, 60], 'level_3': ['alpha','beta','gamma','delta','kappa','omega'], 'level_1': [1, 2, 3, 4, 5, 6], 'level_2': ['A', 'B', 'C', 'D', 'E', 'F'] } df1 = pd.DataFrame(data1) df1.set_index(['level_1', 'level_2','level_3'], inplace = True) # 定义df2 data2 = { 'value': [300, 200], 'level_5': ['jersey','michigan'], 'level_2': ['A', 'B'], 'level_1': [1, 2] } df2 = pd.DataFrame(data2) df2.set_index(['level_1', 'level_2','level_5'], inplace = True) # 自动识别共同索引名 common_index_names = list(set(df1.index.names) & set(df2.index.names)) common_index_names = [name for name in df1.index.names if name in common_index_names] # 处理df2并更新df1 df2_filtered = df2.reset_index()[common_index_names + ['value']] df2_filtered.set_index(common_index_names, inplace=True) df1.update(df2_filtered) print(df1)
输出结果:
value level_1 level_2 level_3 1 A alpha 300.0 2 B beta 200.0 3 C gamma 30.0 4 D delta 40.0 5 E kappa 50.0 6 F omega 60.0
说明
update方法会根据索引精确匹配,仅用df2_filtered中的非NaN值覆盖df1对应行的同名列- 自动识别共同索引的逻辑无需预先指定索引名称,适用于任意带多索引的DataFrame匹配场景
内容的提问来源于stack exchange,提问作者Arindam
相关产品推荐
相关产品推荐

