基于年份索引,用Pandas实现两个DataFrame对应列值相减的高效方案
高效实现Pandas DataFrame按年份匹配计算差值
数据结构
df1(多级索引:state为一级索引,year为二级索引)
state year val1 ALABAMA 2012 22.186789 2016 27.725147 2020 25.461653 ALASKA 2012 13.988918 2016 14.730641 2020 10.061191 ARIZONA 2012 9.064766 2016 3.543962 2020 -0.308710
df2(year为索引)
year val2 2000 -0.491702 2004 2.434132 2008 -7.399984 2012 -3.935184 2016 -2.181941 2020 -4.448889
需求
给df1新增difference列,值为对应行的val1减去df2中同一年份的val2。
原实现方式(for循环)
for i in range(2012, 2024, 4): df1.loc[(slice(None), i), 'difference'] = df1.loc[(slice(None), i), 'val1'] - df2.loc[i]['val2']
更高效的实现方案
方案1:用map匹配年份取值
直接提取df1的year二级索引,通过map从df2中获取对应val2值,再做减法:
df1['difference'] = df1['val1'] - df1.index.get_level_values('year').map(df2['val2'])
方案2:转字典后映射
把df2转换成{年份: val2}的字典,再通过year索引匹配取值:
val2_dict = df2['val2'].to_dict() df1['difference'] = df1['val1'] - df1.index.get_level_values('year').map(val2_dict)
方案3:重置索引后合并计算
如果不习惯多级索引操作,可以先重置df1索引为普通列,合并后计算再恢复原索引:
# 重置df1索引为普通列 df1_reset = df1.reset_index() # 按year合并df2 merged = df1_reset.merge(df2, on='year', how='left') # 计算差值 merged['difference'] = merged['val1'] - merged['val2'] # 恢复原多级索引 df1 = merged.set_index(['state', 'year'])
以上方案均采用Pandas向量化操作,避免了循环遍历,在数据量较大时效率远高于原for循环实现。
内容的提问来源于stack exchange,提问作者Felix
相关产品推荐
相关产品推荐

