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

Pandas向700万行DataFrame添加少量行耗时过长问题排查

高效向大DataFrame添加少量行的解决方案

问题原因分析

  1. pd.concat 耗时久的核心原因:使用 ignore_index=True 时,pandas会为拼接后的新DataFrame重新生成连续索引,这需要复制700万行的全部数据并重新分配内存,带来巨大开销。
  2. df.loc 首次插入慢的原因:DataFrame创建时会预分配固定大小的内存,首次插入超出当前行数的行时,会触发内存扩容操作——重新申请更大的内存块并复制原有所有数据,这就是首次插入耗时极长的原因,后续插入因内存已扩容,速度明显提升。

优化方案

方案1:避免索引重生成,手动对齐索引

通过为小DataFrame设置连续的后续索引,跳过ignore_index=True的全量索引重建:

import pandas as pd
import datetime

rootPath = '/fullPathHere/'
start_time = datetime.datetime.now()
df = pd.read_parquet(rootPath + 'HistoricData.parquet', engine='fastparquet')
print(datetime.datetime.now() - start_time, len(df.index), 'DF read')

start_time = datetime.datetime.now()
df_csv = pd.read_csv(rootPath + 'Full.csv')
# 确保小DF的列与大DF完全一致(避免列对齐开销)
df_csv = df_csv[df.columns]
print(datetime.datetime.now() - start_time, len(df_csv.index), 'CSV read')

start_time = datetime.datetime.now()
df = df.reset_index(drop=True)
# 为小DF设置从大DF末尾开始的连续索引
df_csv.index = range(len(df), len(df) + len(df_csv))
print(datetime.datetime.now() - start_time, 'Index setup done')

start_time = datetime.datetime.now()
df = pd.concat([df, df_csv])
print(datetime.datetime.now() - start_time, 'concat done')

方案2:转字典列表后重构(最优少量行添加)

对于仅添加少量行的场景,将数据转为字典列表后扩展,再重构DataFrame,避免全量数据复制:

import pandas as pd
import datetime

rootPath = '/fullPathHere/'
start_time = datetime.datetime.now()
df = pd.read_parquet(rootPath + 'HistoricData.parquet', engine='fastparquet')
print(datetime.datetime.now() - start_time, len(df.index), 'DF read')

start_time = datetime.datetime.now()
df_csv = pd.read_csv(rootPath + 'Full.csv')
df_csv = df_csv[df.columns]
print(datetime.datetime.now() - start_time, len(df_csv.index), 'CSV read')

start_time = datetime.datetime.now()
# 转成字典列表
full_data = df.to_dict('records')
full_data.extend(df_csv.to_dict('records'))
# 重构DataFrame
df = pd.DataFrame(full_data)
print(datetime.datetime.now() - start_time, 'Data merged done')

方案3:使用轻量内部方法(临时场景)

df.append已被官方弃用,但内部的_append方法实现更轻量,适合临时快速拼接:

# 替换concat或loc的步骤
df = df._append(df_csv, ignore_index=True)

关键注意事项

  • 必须确保两个DataFrame的列名、数据类型完全一致,否则会触发列对齐的额外开销,甚至生成NaN值。可通过df_csv = df_csv[df.columns]强制列顺序一致。
  • 方案2的优势在于仅处理少量新增行,内存开销极低,通常能把耗时控制在0.1-0.5秒内。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:10:26