如何用Pandas add()处理索引部分重叠的多个DataFrame相加?
Python/Pandas: 合并多个时间范围错开的DataFrame并求和
这个问题我之前也碰到过,核心就是解决非重叠时间索引的数值保留+重叠索引数值求和的需求,不用太复杂,两种简单方法就能搞定:
方法一:用add()的fill_value参数
pandas.DataFrame.add()其实本身就支持处理非重叠索引的情况,只需要设置fill_value=0就行——这样当两个DataFrame索引不重叠时,缺失的那一方会用0来填充,和另一方的数值相加后就保留了原数值,而不是变成NaN。
举个实际的例子,先构造示例数据:
import pandas as pd import numpy as np # 构造第一个DataFrame,时间9:00-15:00 times1 = pd.date_range('2017-10-02 09:00', '2017-10-02 15:00', freq='H') df1 = pd.DataFrame({'col1': np.random.randn(len(times1)), 'col2': np.random.randn(len(times1))}, index=times1) # 构造第二个DataFrame,时间10:00-16:00 times2 = pd.date_range('2017-10-02 10:00', '2017-10-02 16:00', freq='H') df2 = pd.DataFrame({'col1': np.random.randn(len(times2)), 'col2': np.random.randn(len(times2))}, index=times2)
如果直接用df1.add(df2),09:00和16:00的位置会是NaN,但改成下面这样就没问题了:
result = df1.add(df2, fill_value=0)
要是你有n个DataFrame,不用一个个手动加,用functools.reduce批量合并就行:
from functools import reduce # 把所有DataFrame放到一个列表里 dfs = [df1, df2, df3, ...] # 批量合并求和 final_result = reduce(lambda x, y: x.add(y, fill_value=0), dfs)
方法二:pd.concat + groupby求和
另一种思路是先把所有DataFrame合并成一个大表,再按时间索引分组求和——这样相同时间点的数值会被加起来,单个时间点的数值就保留原样。
代码示例:
# 合并所有DataFrame combined_df = pd.concat(dfs) # 按索引分组求和 final_result = combined_df.groupby(combined_df.index).sum()
两种方法的小区别
- 如果你的所有DataFrame列名完全一致,两种方法效果一样。
add()+reduce的方法在数据量较大时效率会更高一点;concat+groupby的方式更灵活,要是后续有其他分组需求,调整起来更方便。
内容的提问来源于stack exchange,提问作者dejoma
相关产品推荐
相关产品推荐

