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

Python实现DataFrame时间序列筛选、重采样后横向拼接的方法咨询

实现方案

你可以按以下步骤实现,逻辑清晰且能覆盖所有需求:

第一步:数据预处理

先统一两个表的时间字段格式,同时给df1计算每个记录对应的时间窗口起止时间:

import pandas as pd

# 转换时间字段格式
df1['Date'] = pd.to_datetime(df1['Date'])
df2['Timestamp'] = pd.to_datetime(df2['Timestamp'])

# 计算每个记录的时间窗口:前10天0点 ~ 当日23:59:59
df1['start_ts'] = df1['Date'] - pd.Timedelta(days=10)
df1['end_ts'] = df1['Date'] + pd.Timedelta(days=1) - pd.Timedelta(seconds=1)

第二步:逐行处理生成时间序列特征

对于df1的每一条记录,筛选df2匹配数据后做重采样、填充,最终转成横向的14400列:

def generate_time_features(row):
    # 1. 筛选当前Id对应时间范围内的Value数据
    filter_mask = (
        (df2['Id'] == row['Id']) &
        (df2['Timestamp'] >= row['start_ts']) &
        (df2['Timestamp'] <= row['end_ts'])
    )
    tmp = df2.loc[filter_mask, ['Timestamp', 'Value']].set_index('Timestamp').sort_index()

    # 2. 生成刚好14400个点的完整1min间隔时间序列
    full_time_range = pd.date_range(start=row['start_ts'], end=row['end_ts'], freq='1min')

    # 3. 1min重采样 + 填充缺失值
    # 若1分钟内有多个值,默认取均值,可替换为first()/max()等符合业务需求的聚合规则
    resampled = tmp.resample('1min').mean()
    # 对齐完整时间序列后,先后执行后向填充、前向填充
    filled = resampled.reindex(full_time_range).bfill().ffill()['Value'].values

    # 4. 返回成横向的value1~value14400序列
    return pd.Series(filled, index=[f'value{i+1}' for i in range(14400)])

# 执行处理并拼接结果
final_result = pd.concat(
    [df1.drop(columns=['start_ts', 'end_ts']), df1.apply(generate_time_features, axis=1)],
    axis=1
)

大数据量优化方案

如果你的df1记录数过万、df2数据量超过百万级,逐行apply效率较低,可以用预关联+分组的方式提速:

# 先按Id关联两个表,再过滤符合时间范围的记录
merged_df = df2.merge(df1[['Id', 'Date', 'start_ts', 'end_ts']], on='Id', how='inner')
merged_df = merged_df[
    (merged_df['Timestamp'] >= merged_df['start_ts']) &
    (merged_df['Timestamp'] <= merged_df['end_ts'])
]

# 按Id+Date分组处理每个组的时间序列
def process_group(group):
    # 取当前组对应的时间窗口
    group_info = df1[(df1['Id'] == group.name[0]) & (df1['Date'] == group.name[1])].iloc[0]
    full_time_range = pd.date_range(start=group_info['start_ts'], end=group_info['end_ts'], freq='1min')
    resampled = group.set_index('Timestamp')['Value'].resample('1min').mean()
    filled = resampled.reindex(full_time_range).bfill().ffill().values
    return pd.Series(filled, index=[f'value{i+1}' for i in range(14400)])

# 生成时间特征列后和df1拼接
value_features = merged_df.groupby(['Id', 'Date']).apply(process_group).reset_index()
final_result = df1.drop(columns=['start_ts', 'end_ts']).merge(value_features, on=['Id', 'Date'], how='left')

注意事项

  • 若某条记录在对应时间范围内完全没有匹配的Value数据,填充后所有value列会是NaN,可根据业务需求额外加fillna(默认值)处理
  • 1分钟重采样的聚合规则可自行调整,比如需要取每分钟第一个值,把mean()替换为first()即可
  • 用左连接可保留df1的所有原始记录,即使没有匹配到df2的数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:15:01