如何通过索引合并多个Pandas DataFrames?
解决多地区销量DataFrame合并问题
嗨Stephen,别晕啦!你的问题其实是Pandas合并操作里的常见小坑,我帮你拆解并搞定:
先说说你当前代码里的几个问题
- drop操作没生效:Pandas的
drop()默认返回新的DataFrame,不会修改原对象,你写的d2.drop(d2.index[[2,3]])其实没改变原来的d2,得把结果赋值回去,比如d2 = d2.drop(d2.index[[2,3]]) - merge默认是内连接:你用
pd.merge()的时候,默认是how='inner',只会保留所有DataFrame都存在的时间点,这就是为什么你的结果里没有缺失值的原因,我们需要改成外连接how='outer' - 列名笔误:你的d3里错误地用了
UK列,应该是CAN,这会导致合并后出现UK_x、UK_y的重复列
正确实现方法
最简洁高效的方式是用pd.concat(),因为你的所有DataFrame都是以time为索引(或time列),concat会自动按索引对齐,默认就是外连接,缺失值自动填充NaN。当然也可以修正merge的方式,我两种都给你:
方法1:使用pd.concat(推荐)
import pandas as pd # 先构造正确的示例数据(模拟你的场景) ts = pd.DataFrame({'time': pd.date_range('2012-12-01', periods=9)}) d1 = ts.copy() d1['USA'] = [1,1,1,3,5,6,4,2,5] d1.set_index('time', inplace=True) d2 = ts.copy() d2['UK'] = [1,1,5,6,4,2,5] # 删掉索引2、3对应的行(对应12-3、12-4) d2 = d2.drop(d2.index[[2,3]]) d2.set_index('time', inplace=True) d3 = ts.copy() d3['CAN'] = [1,1,3,4,2,5] # 删掉索引2、4、6对应的行(对应12-3、12-5、12-7) d3 = d3.drop(d3.index[[2,4,6]]) d3.set_index('time', inplace=True) dataframes = [d1, d2, d3] # 按索引合并,外连接,缺失值填充NaN df_final = pd.concat(dataframes, axis=1) print(df_final)
方法2:修正reduce+pd.merge的方式
如果你坚持要用reduce和merge,需要指定how='outer',并且确保列名不重复:
from functools import reduce # 先确保每个DataFrame的time列存在且列名唯一(比如d3用CAN列) df_final = reduce(lambda left, right: pd.merge(left, right, on='time', how='outer'), dataframes)
最终结果
运行后你会得到和你期望完全一致的结果:
| time | USA | UK | CAN |
|---|---|---|---|
| 2012-12-01 | 1 | 1 | 1 |
| 2012-12-02 | 1 | 1 | 1 |
| 2012-12-03 | 1 | NaN | NaN |
| 2012-12-04 | 3 | NaN | 3 |
| 2012-12-05 | 5 | 5 | NaN |
| 2012-12-06 | 6 | 6 | 4 |
| 2012-12-07 | 4 | 4 | NaN |
| 2012-12-08 | 2 | 2 | 2 |
| 2012-12-09 | 5 | 5 | 5 |
内容的提问来源于stack exchange,提问作者Roughrider
相关产品推荐
相关产品推荐

