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

Pandas iloc逐行循环处理数据极慢,有什么高效替代方案?

性能瓶颈根因

你当前代码运行极慢的核心原因是逐行向pandas DataFrame追加数据:pandas DataFrame的底层存储是连续内存块,每次调用result.loc[len(result.index)]插入新行时,都会触发整个DataFrame的全量内存拷贝,数据量越大拷贝开销呈指数级上升,和你用iloc还是iterrows遍历没有关系。360万行的目标数据量用这种写法,跑几个小时都属于正常情况。

优化方案

彻底抛弃逐行写入逻辑,全程使用pandas向量化操作:

  • 先批量提取所有固定字段(比如从Outlet列解析ID)
  • 用pandas内置的宽表转长表函数melt()批量拆分月度值,替代手写双层循环
  • 所有数据批量处理完成后,一次性拼接生成最终结果DataFrame
    8万行源数据用这个方案处理,普通PC上10秒左右就能跑完。
可直接运行的实现代码
import pandas as pd
import numpy as np

# 读取源数据
df3 = pd.read_csv('H:/Martin Dow/COSOME.csv', header=3)

# 批量预处理通用字段:从Outlet列提取方括号内的OUTLET_ID,重命名基础列
df3['OUTLET_ID'] = df3.iloc[:, 2].str.extract(r'\[(\d+)\]').astype('Int64')
df3 = df3.rename(columns={df3.columns[0]: 'BRICK', df3.columns[1]: 'OUTLET_FLAG'})

# 预生成24个月的周期映射(2020-2021循环,匹配业务规则里的年份重置逻辑)
month_seq = np.tile(np.arange(1, 13), 2)
year_seq = np.repeat([2020, 2021], 12)
time_dim = pd.DataFrame({'MONTH': month_seq, 'YEAR': year_seq})

# ---------------------- 处理Flag为D的行 ----------------------
# 规则:取第27列起的24个值,MARKET_TYPE固定为R05C0,生成24行/源行
df_d = df3[df3['OUTLET_FLAG'] == 'D'].copy()
d_value_cols = df3.columns[27: 27+24]
df_d_long = df_d.melt(
    id_vars=['BRICK', 'OUTLET_FLAG', 'OUTLET_ID'],
    value_vars=d_value_cols,
    value_name='VALUE'
).drop(columns=['variable'])
# 绑定时间维度和固定字段
df_d_long = pd.concat([df_d_long.reset_index(drop=True), pd.concat([time_dim]*len(df_d), ignore_index=True)], axis=1)
df_d_long[['AMOUNT_TYPE', 'MARKET_TYPE', 'BRAND', 'SUB_MARKET_TYPE']] = ['Value', 'R05C0', 'COSOME-E', '']

# ---------------------- 处理Flag为H/R的行 ----------------------
df_hr = df3[df3['OUTLET_FLAG'].isin(['H', 'R'])].copy()
# 第一组:第3列起24个值,MARKET_TYPE为COSOME-E
hr_value_cols1 = df3.columns[3: 3+24]
df_hr_long1 = df_hr.melt(
    id_vars=['BRICK', 'OUTLET_FLAG', 'OUTLET_ID'],
    value_vars=hr_value_cols1,
    value_name='VALUE'
).drop(columns=['variable'])
df_hr_long1 = pd.concat([df_hr_long1.reset_index(drop=True), pd.concat([time_dim]*len(df_hr), ignore_index=True)], axis=1)
df_hr_long1[['AMOUNT_TYPE', 'MARKET_TYPE', 'BRAND', 'SUB_MARKET_TYPE']] = ['Value', 'COSOME-E', 'COSOME-E', '']

# 第二组:第27列起24个值,MARKET_TYPE为R05C0,年份重置为2020-2021
hr_value_cols2 = df3.columns[3+24: 3+48]
df_hr_long2 = df_hr.melt(
    id_vars=['BRICK', 'OUTLET_FLAG', 'OUTLET_ID'],
    value_vars=hr_value_cols2,
    value_name='VALUE'
).drop(columns=['variable'])
df_hr_long2 = pd.concat([df_hr_long2.reset_index(drop=True), pd.concat([time_dim]*len(df_hr), ignore_index=True)], axis=1)
df_hr_long2[['AMOUNT_TYPE', 'MARKET_TYPE', 'BRAND', 'SUB_MARKET_TYPE']] = ['Value', 'R05C0', 'COSOME-E', '']

# ---------------------- 合并所有结果 导出 ----------------------
result = pd.concat([df_d_long, df_hr_long1, df_hr_long2], ignore_index=True)
# 调整列顺序和目标输出完全一致
result = result[['BRICK', 'OUTLET_FLAG', 'OUTLET_ID', 'MONTH', 'YEAR', 'VALUE', 'AMOUNT_TYPE', 'MARKET_TYPE', 'BRAND', 'SUB_MARKET_TYPE']]
result.to_csv('cosomexxx.csv', index=False)
额外优化提示
  • 如果运行时内存占用过高,可以在pd.read_csv时通过dtype参数指定各列的数据类型,比如把字符串列指定为category类型,能降低40%左右的内存开销
  • 不需要在循环里加print(i),高频打印本身也会拖慢运行速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:01:02