如何按日期合并多列不同的Pandas时间序列DataFrame并求和
问题需求
我有数百个时间序列Pandas DataFrame,每个代表不同对象,都包含dates列和一个无用索引列,其余数据列存在差异(有的包含全部列,有的包含部分列,有的完全没有)。需要按dates列合并这些DataFrame,对同名数据列求和,最终得到包含所有列、按日期聚合求和的结果(全NaN的单元格保留NaN)。
示例数据
DF#1
| index | dates | 1000 | 1001 | 1002 | 1012 | 1014 |
|---|---|---|---|---|---|---|
| 0 | 2023-01-31 | 1 | NaN | 1 | 1 | 1 |
| 1 | 2023-02-01 | 1 | 1 | 10 | 1 | 1 |
| 2 | 2023-02-02 | 1 | 2 | NaN | 1 | 1 |
| 3 | 2023-02-03 | 2 | 3 | 1 | 1 | 1 |
| 4 | 2023-02-04 | 2 | 3 | 1 | NaN | 1 |
| 5 | 2023-02-05 | 3 | 3 | 1 | 1 | 1 |
| 6 | 2023-02-06 | 4 | 4 | 1 | 1 | 1 |
| 7 | 2023-02-07 | 4 | 5 | 1 | 1 | 1 |
DF#2
| index | dates | 1000 | 1001 | 1003 | 1006 | 2001 |
|---|---|---|---|---|---|---|
| 0 | 2023-01-31 | 1 | NaN | 1 | 1 | 1 |
| 1 | 2023-02-01 | 1 | 1 | 10 | 1 | 1 |
| 2 | 2023-02-02 | 1 | 2 | NaN | 1 | 1 |
| 3 | 2023-02-03 | 2 | 3 | 1 | 1 | 1 |
| 4 | 2023-02-04 | 2 | 3 | 1 | NaN | 1 |
| 5 | 2023-02-05 | 3 | NaN | 1 | 1 | 1 |
| 6 | 2023-02-06 | 4 | 4 | 1 | 1 | 1 |
| 7 | 2023-02-07 | 4 | 5 | 1 | 1 | 1 |
DF#3
| index | dates | 1000 | 1001 | 1003 | 1012 | 1014 |
|---|---|---|---|---|---|---|
| 0 | 2023-01-31 | 1 | 1 | 1 | 1 | 1 |
| 1 | 2023-02-01 | 1 | NaN | 10 | 1 | 1 |
| 2 | 2023-02-02 | 1 | 2 | NaN | 1 | 1 |
| 3 | 2023-02-03 | 2 | 3 | 1 | 1 | 1 |
| 4 | 2023-02-04 | 2 | 3 | 1 | NaN | 1 |
| 5 | 2023-02-05 | 3 | 3 | 1 | 1 | 1 |
| 6 | 2023-02-06 | 4 | 4 | 1 | 1 | 1 |
| 7 | 2023-02-07 | 4 | 5 | 1 | NaN | 1 |
期望结果DF
| index | dates | 1000 | 1001 | 1002 | 1003 | 1006 | 1012 | 1014 | 2001 |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023-01-31 | 3 | 1 | 1 | 2 | 1 | 2 | 2 | 1 |
| 1 | 2023-02-01 | 3 | 2 | 10 | 20 | 1 | 2 | 2 | 1 |
| 2 | 2023-02-02 | 3 | 6 | NaN | NaN | 1 | 2 | 2 | 1 |
| 3 | 2023-02-03 | 6 | 9 | 1 | 2 | 1 | 2 | 2 | 1 |
| 4 | 2023-02-04 | 6 | 9 | 1 | 2 | NaN | NaN | 2 | 2 |
| 5 | 2023-02-05 | 9 | 6 | 1 | 2 | 1 | 2 | 2 | 1 |
| 6 | 2023-02-06 | 12 | 12 | 1 | 2 | 1 | 2 | 2 | 1 |
| 7 | 2023-02-07 | 12 | 15 | 1 | 2 | 1 | 1 | 2 | 1 |
解决方案
步骤说明
- 移除所有DataFrame中的无用索引列;
- 拼接所有DataFrame,保留所有列,缺失值补NaN;
- 按
dates列分组,对每列求和(若该日期下该列全为NaN则保留NaN,否则求和非NaN值); - 重置索引并调整列顺序以匹配期望结果。
代码实现
import pandas as pd import numpy as np # 假设所有DataFrame存储在列表dfs中,例如:dfs = [df1, df2, df3] # 第一步:移除无用索引列 for df in dfs: df.drop('index', axis=1, inplace=True) # 第二步:拼接所有DataFrame combined = pd.concat(dfs, ignore_index=True) # 第三步:按dates分组聚合,自定义求和逻辑 result = combined.groupby('dates', as_index=False).agg( lambda x: x.sum(skipna=True) if x.notna().any() else np.nan ) # 第四步:重置索引并调整列顺序 result.reset_index(drop=False, inplace=True) # 按期望结果的列顺序调整 column_order = ['index', 'dates', '1000', '1001', '1002', '1003', '1006', '1012', '1014', '2001'] result = result[column_order]
代码说明
pd.concat会自动合并所有列,不存在的列填充NaN,完美适配列不统一的场景;- 自定义聚合函数确保:当某日期下某列的所有值都是NaN时,结果保留NaN;否则对所有非NaN值求和,符合预期结果要求;
- 最后调整列顺序是为了和示例期望结果完全一致,若不需要严格顺序可省略该步骤。
内容的提问来源于stack exchange,提问作者Simon Plant
相关产品推荐
相关产品推荐

