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

如何将Pandas DataFrame行对齐到最近的6分钟时间步长并设置索引频率

背景

我有一个包含数十万条数值的大型DataFrame,其头部数据如下所示:

df = pd.DataFrame([np.nan, 1100, 1400, np.nan, 14000],
                   index=pd.to_datetime(["2011-05-25 10:00:00",
                                         "2011-05-25 16:40:00",
                                         "2011-05-25 17:06:00",
                                         "2011-05-25 17:10:00",
                                         "2011-05-25 17:24:00"]))
# 输出预览
                           0
2011-05-25 10:00:00      NaN
2011-05-25 16:40:00   1100.0
2011-05-25 17:06:00   1400.0
2011-05-25 17:10:00      NaN
2011-05-25 17:24:00  14000.0

需求

数据的记录时间不都是6分钟步长,我需要将未在6分钟时间步长上记录的值移动到最近的6分钟步长,得到的新DataFrame示例如下:

n_df = pd.DataFrame([np.nan, 1100, 1400, np.nan, 14000],
                   index=pd.to_datetime(["2011-05-25 10:00:00",
                                         "2011-05-25 16:42:00",
                                         "2011-05-25 17:06:00",
                                         "2011-05-25 17:12:00",
                                         "2011-05-25 17:24:00"])
                   )
# 输出预览
                           0
2011-05-25 10:00:00      NaN
2011-05-25 16:42:00   1100.0
2011-05-25 17:06:00   1400.0
2011-05-25 17:12:00      NaN
2011-05-25 17:24:00  14000.0

核心要求是n_df中所有值都对应6分钟时间步长,且n_df.index.freq属性不能为None。目前通过for循环遍历df查找最近6分钟步长并迁移值,当df数据量超过1000条时运行速度极慢,需要更高效的实现方法。

已尝试的实现方案

index = pd.date_range(df.index[0], end=df.index[-1], freq="6min")
pydatetime_index = index.to_pydatetime()
n_df = pd.DataFrame(columns=df.columns, index=index)

for _idx, i in enumerate(df.index):
    nearest_neighbor = np.abs(pydatetime_index - i.to_pydatetime())
    idx = np.argmin(nearest_neighbor)
    val = df.loc[i]
    n_df.iloc[idx] = val

高效解决方案

直接使用pandas内置的向量化时间处理能力即可实现需求,几十万条数据可在毫秒级完成处理,代码如下:

import pandas as pd
import numpy as np

# 1. 将原数据的时间索引对齐到最近的6分钟步长
df_aligned = df.copy()
df_aligned.index = df_aligned.index.round(freq='6T') # 6T代表6分钟,也可写为'6min'

# 2. 生成覆盖原时间范围的完整6分钟步长索引
full_time_index = pd.date_range(
    start=df.index.min(),
    end=df.index.max(),
    freq='6T'
)

# 3. 先聚合落入同一时间步长的重复值(默认取第一个值,可按需改为sum/mean等),再补全所有时间步长
n_df = df_aligned.groupby(level=0).first().reindex(full_time_index)

方案说明

  • 完全匹配需求:最终输出的n_df索引为严格的6分钟步长,n_df.index.freq值为6T,不会为None
  • 效率提升显著:原循环方案时间复杂度为O(n*m)(n为原数据长度,m为目标索引长度),本方案为纯向量化操作,时间复杂度为O(n),处理数十万条数据无压力
  • 对齐规则可灵活调整:如果需要向下取整到前一个6分钟步长,将round改为floor;如果需要向上取整到后一个6分钟步长,改为ceil即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:27:03