如何在Python的DataFrame中按历史时间序列值进行数据聚合?
按历史时间序列聚合DataFrame的实现方案
嘿,针对你的时间序列聚合需求,我来一步步给你拆解实现方法~首先先明确你的数据结构:每个ID(这里都是A)每天有三个时间点的value记录,我们需要先把日期和时间合并成完整的时间戳,这样才能正确按时间序列排序和聚合。
第一步:预处理时间列
先把date和time合并成完整的datetime字段,同时确保数据按时间有序:
import pandas as pd d = {'ID':["A","A","A","A","A","A","A","A","A","A","A","A"], 'date':["2017-01-01","2017-01-01","2017-01-01","2017-01-02","2017-01-02","2017-01-02","2017-01-03","2017-01-03", "2017-01-03","2017-01-04","2017-01-04","2017-01-04"], 'time':["00:00","06:00","12:00","00:00","06:00","12:00","00:00","06:00","12:00","00:00","06:00","12:00"], 'value':[23,100,330,57,122,477,46,99,469,37,118,499]} df = pd.DataFrame(data=d) df['date'] = pd.to_datetime(df['date']) # 合并日期和时间为完整datetime列 df['datetime'] = pd.to_datetime(df['date'].astype(str) + ' ' + df['time']) # 按ID和时间排序(确保序列有序,避免后续聚合出错) df = df.sort_values(['ID', 'datetime']).reset_index(drop=True)
常见的历史聚合场景实现
1. 累计历史聚合(从序列起始到当前时间的统计)
这是最常用的场景:计算每个时间点对应的从第一个记录到当前的累计值,比如累计总和、均值、最大值等:
# 按ID分组(如果后续有多个ID,这个分组会自动适配) df['cum_sum'] = df.groupby('ID')['value'].cumsum() df['cum_mean'] = df.groupby('ID')['value'].expanding().mean().reset_index(level=0, drop=True) df['cum_max'] = df.groupby('ID')['value'].cummax()
比如2017-01-01 12:00的cum_sum就是23+100+330=453,完美对应历史序列的累计逻辑。
2. 滚动时间窗口聚合(最近N个时间点/时间段)
如果需要聚焦最近一段时间或最近k个记录的聚合,比如最近3个时间点的均值、最近1天内的总和:
按最近N个记录滚动
# 滚动窗口大小为3(包含当前记录在内的最近3条),min_periods=1表示即使不足3条也计算 df['rolling_3_mean'] = df.groupby('ID')['value'].rolling(window=3, min_periods=1).mean().reset_index(level=0, drop=True) df['rolling_3_sum'] = df.groupby('ID')['value'].rolling(window=3, min_periods=1).sum().reset_index(level=0, drop=True)
按时间跨度滚动(比如最近1天)
# 按时间窗口1天聚合,自动匹配每个时间点过去1天内的所有记录 df['rolling_1d_sum'] = df.groupby('ID').rolling(window='1D', on='datetime')['value'].sum().reset_index(level=0, drop=True)
3. 按日期维度的历史聚合
如果需要先按日期汇总每日数据,再计算历史日期的累计:
# 先按ID和日期分组,计算每日value总和 daily_df = df.groupby(['ID', 'date'])['value'].sum().reset_index(name='daily_sum') # 计算从第一天到当前日期的累计总和 daily_df['cum_daily_sum'] = daily_df.groupby('ID')['daily_sum'].cumsum()
比如2017-01-02的cum_daily_sum就是1月1日总和(453)+1月2日总和(656)=1109。
4. 自定义历史聚合逻辑
如果有特殊需求(比如计算历史中位数),可以用apply结合自定义函数:
def custom_historical_agg(series): # series参数是当前点及之前的所有value数据 return series.median() df['hist_median'] = df.groupby('ID')['value'].expanding().apply(custom_historical_agg).reset_index(level=0, drop=True)
内容的提问来源于stack exchange,提问作者Jiayu Zhang
相关产品推荐
相关产品推荐

