You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pandas concat对多DataFrame的DatetimeIndex列求和异常问题

问题:聚合多带DatetimeIndex的DataFrame(外连接索引+同日期求和)

我有多个带有DatetimeIndex的DataFrame,它们的日期各不相同,但列结构一致。希望聚合这些DataFrame时,索引采用外连接方式保留所有日期,同一日期的列值进行求和。

最小可复现代码

#!/usr/bin/env python3

import os, sys
import numpy as np
import pandas as pd
import datetime as dt

days1 = pd.date_range(dt.date(2010,1,1), dt.date(2010,1,1) + dt.timedelta(7), freq='D')
days2 = pd.date_range(dt.date(2010,1,3), dt.date(2010,1,3) + dt.timedelta(7), freq='D')
days3 = pd.date_range(dt.date(2010,2,1), dt.date(2010,2,1) + dt.timedelta(7), freq='D')

df1 = pd.DataFrame({'date': days1, 'alpha': np.array(8*[1]), 'beta': np.array(8*[10])})
df2 = pd.DataFrame({'date': days2, 'alpha': np.array(8*[2]), 'beta': np.array(8*[20])})
df3 = pd.DataFrame({'date': days3, 'alpha': np.array(8*[3]), 'beta': np.array(8*[30])})

df1 = df1.set_index('date')
df2 = df2.set_index('date')
df3 = df3.set_index('date')

df1 = (pd.concat([df1,df2], axis=0)).groupby('date')['alpha', 'beta'].sum().reset_index()
df1 = (pd.concat([df1,df3], axis=0)).groupby('date')['alpha', 'beta'].sum().reset_index()

print(df1)

实际输出

date  alpha  beta
0 2010-01-01      1    10
1 2010-01-02      1    10
2 2010-01-03      3    30
3 2010-01-04      3    30
4 2010-01-05      3    30
5 2010-01-06      3    30
6 2010-01-07      3    30
7 2010-01-08      3    30
8 2010-01-09      2    20
9 2010-01-10      2    20

预期输出

date  alpha  beta
 0 2010-01-01      1    10
 1 2010-01-02      1    10
 2 2010-01-03      3    30
 3 2010-01-04      3    30
 4 2010-01-05      3    30
 5 2010-01-06      3    30
 6 2010-01-07      3    30
 7 2010-01-08      3    30
 8 2010-01-09      2    20
 9 2010-01-10      2    20
10 2010-02-01      3    30
11 2010-02-02      3    30
12 2010-02-03      3    30
13 2010-02-04      3    30
14 2010-02-05      3    30
15 2010-02-06      3    30
16 2010-02-07      3    30
17 2010-02-08      3    30

问题原因

第二次执行concat时,df1已经通过reset_index()将date转为普通列,而df3仍以date为DatetimeIndex。concat会自动对齐双方的索引,导致df3的内容被匹配到df1的整数索引上,最终groupby时丢失了df3的日期数据。

解决方案

方案1:一次性合并所有DataFrame再分组求和(推荐)

一次性合并所有目标DataFrame,再按日期索引分组求和,避免分步操作的索引不一致问题,效率更高:

#!/usr/bin/env python3
import numpy as np
import pandas as pd
import datetime as dt

days1 = pd.date_range(dt.date(2010,1,1), dt.date(2010,1,1) + dt.timedelta(7), freq='D')
days2 = pd.date_range(dt.date(2010,1,3), dt.date(2010,1,3) + dt.timedelta(7), freq='D')
days3 = pd.date_range(dt.date(2010,2,1), dt.date(2010,2,1) + dt.timedelta(7), freq='D')

df1 = pd.DataFrame({'date': days1, 'alpha': np.array(8*[1]), 'beta': np.array(8*[10])}).set_index('date')
df2 = pd.DataFrame({'date': days2, 'alpha': np.array(8*[2]), 'beta': np.array(8*[20])}).set_index('date')
df3 = pd.DataFrame({'date': days3, 'alpha': np.array(8*[3]), 'beta': np.array(8*[30])}).set_index('date')

# 一次性合并所有DataFrame,按索引(日期)分组求和后重置索引
result = pd.concat([df1, df2, df3], axis=0).groupby(level=0).sum().reset_index()
print(result)

方案2:保持统一索引状态分步处理

如果需要分步合并,确保每次合并的DataFrame都保持date为DatetimeIndex,不要提前重置索引:

#!/usr/bin/env python3
import numpy as np
import pandas as pd
import datetime as dt

days1 = pd.date_range(dt.date(2010,1,1), dt.date(2010,1,1) + dt.timedelta(7), freq='D')
days2 = pd.date_range(dt.date(2010,1,3), dt.date(2010,1,3) + dt.timedelta(7), freq='D')
days3 = pd.date_range(dt.date(2010,2,1), dt.date(2010,2,1) + dt.timedelta(7), freq='D')

df1 = pd.DataFrame({'date': days1, 'alpha': np.array(8*[1]), 'beta': np.array(8*[10])}).set_index('date')
df2 = pd.DataFrame({'date': days2, 'alpha': np.array(8*[2]), 'beta': np.array(8*[20])}).set_index('date')
df3 = pd.DataFrame({'date': days3, 'alpha': np.array(8*[3]), 'beta': np.array(8*[30])}).set_index('date')

# 第一次合并后不重置索引,保持date为索引
df_combined = pd.concat([df1, df2], axis=0).groupby('date').sum()
# 第二次合并时,双方都是DatetimeIndex,合并后再分组求和并重置索引
df_combined = pd.concat([df_combined, df3], axis=0).groupby('date').sum().reset_index()
print(df_combined)

两种方案都能得到你想要的预期输出。

内容的提问来源于stack exchange,提问作者gman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:29:53