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

Pandas时间区间粒度转换性能优化求助

高效解决Pandas日期区间展开性能问题

原代码的性能瓶颈分析

你的代码运行极慢的核心原因有两个:

  • 逐行循环(iterrows()):Python层面的逐行处理完全没有利用Pandas的向量化优势,对于715K行的数据集来说,这种循环的开销极大。
  • 频繁append()操作:每次df2.append()都会创建新的DataFrame,涉及大量内存分配和数据复制,随着数据量增长,性能会呈指数级下降。

推荐的高效实现方法

以下两种方法均基于向量化操作,能将处理时间从数小时压缩到几分钟甚至更短。

方法1:apply + date_range + explode(简洁易读)

这是最直观的向量化实现,利用Pandas内置的日期生成和行展开功能:

import pandas as pd

# 先确保日期列是datetime类型(仅需执行一次)
df1['start'] = pd.to_datetime(df1['start'])
df1['end'] = pd.to_datetime(df1['end'])

# 对每行生成日期范围列表,再展开为单独行
df1['Date'] = df1.apply(lambda row: pd.date_range(row['start'], row['end'], freq='D'), axis=1)
df2 = df1.explode('Date').drop(columns=['start', 'end'])

方法2:Numpy广播(极致性能)

如果追求最快速度,用Numpy的广播机制直接构造数据,避免apply的微小开销:

import pandas as pd
import numpy as np

# 转换日期列
df1['start'] = pd.to_datetime(df1['start'])
df1['end'] = pd.to_datetime(df1['end'])

# 计算每行需要展开的天数
df1['repeat_count'] = (df1['end'] - df1['start']).dt.days + 1

# 重复非日期列对应次数
non_date_cols = df1[['ColA', 'ColB', 'ColC']].values.repeat(df1['repeat_count'], axis=0)

# 生成所有日期序列并拼接
date_sequences = np.concatenate(
    df1.apply(lambda row: pd.date_range(row['start'], row['end'], freq='D'), axis=1).values
)

# 构造最终DataFrame
df2 = pd.DataFrame(non_date_cols, columns=['ColA', 'ColB', 'ColC'])
df2['Date'] = date_sequences

额外优化建议

  • 内存管理:7150万行数据会占用大量内存(预计数GB),如果内存不足,可以将原数据集分块处理,每块处理后保存为CSV/Parquet文件,最后合并结果。
  • 提前转换日期类型:原代码中每次循环都调用pd.to_datetime(),这是不必要的重复操作,提前一次性转换能节省大量时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:30:18