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

循环中pd.concat与list.append构建Pandas DataFrame:求更优方案

基于Pandas高效构建全局DataFrame的优化方案

问题描述

我采用两种方法基于Pandas构建全局DataFrame,每行数据来自另一DataFrame的筛选结果:通过循环生成计算列,筛选其中最小值对应的行。了解到循环中使用pd.concat会占用较多内存,但测试发现两种方法耗时差异不大,请问是否存在更优实现方案?

原实现代码

import time
import pandas as pd

technologies = {
    'X' :[20000,25000,22000,30000,50000,10000,30000],
    'Y':[1000,2300,1200,2000,1000,3000,5000]
          }
df = pd.DataFrame(technologies)
start_time = time.time()
df1_result=pd.DataFrame()
for i in range(df.shape[0]):
    df1=df.copy()
    df1['i']=i
    df1['Y']=df1['Y'].shift(-i)
    df1['Dist']=df1['X']-df1['Y']
    idmin=df1['Dist'].idxmin()
    result=pd.DataFrame([df1.iloc[idmin,:]])
    df1_result=pd.concat(([df1_result, result]),  ignore_index=True)
print("--- %s seconds ---" % (time.time() - start_time))

start_time = time.time()
ListResult2=[]
for i in range(df.shape[0]):
    df2=df.copy()
    df2['i']=i
    df2['Y']=df2['Y'].shift(-i)
    df2['Dist']=df2['X']-df2['Y']
    idmin=df2['Dist'].idxmin()
    ListResult2.append(df2.iloc[idmin,:].values.tolist())

df_result2 = pd.DataFrame (ListResult2)

原代码核心问题

原实现的最大开销在于每次循环都完整复制了原DataFrame,这在数据量较大时会导致内存占用飙升;同时循环内重复执行shift和计算逻辑,没有利用Pandas/Numpy的向量化优势。

优化方案:向量化批量计算

通过预先生成所有需要的移位结果,用Numpy矩阵运算批量计算Dist,一次性找到所有循环对应的最小索引,最后组装结果。这种方式彻底避免了循环内的DataFrame复制,大幅提升效率。

优化后代码

import time
import pandas as pd
import numpy as np

technologies = {
    'X' :[20000,25000,22000,30000,50000,10000,30000],
    'Y':[1000,2300,1200,2000,1000,3000,5000]
}
df = pd.DataFrame(technologies)

start_time = time.time()

n = df.shape[0]
Y_vals = df['Y'].values
X_vals = df['X'].values

# 预先生成所有i对应的Y移位结果矩阵:每一列对应一个i的shift(-i)输出
Y_shifted = np.full((n, n), np.nan)
for i in range(n):
    # 前n-i个位置填充Y[i:],剩余位置保持NaN
    Y_shifted[:n-i, i] = Y_vals[i:]

# 批量计算所有i对应的Dist值:X的每个元素与对应i的Y移位值做差
Dist_matrix = X_vals[:, np.newaxis] - Y_shifted

# 找到每个i对应的最小Dist的行索引(自动忽略NaN)
min_row_indices = np.nanargmin(Dist_matrix, axis=0)

# 组装最终结果
optimized_result = []
for i, row_idx in enumerate(min_row_indices):
    row_data = df.iloc[row_idx].copy()
    row_data['i'] = i
    row_data['Dist'] = Dist_matrix[row_idx, i]
    optimized_result.append(row_data)

df_optimized = pd.DataFrame(optimized_result).reset_index(drop=True)

print("--- 优化方案耗时:%s seconds ---" % (time.time() - start_time))

优化效果说明

  • 内存效率:不再循环复制原DataFrame,仅生成必要的矩阵数据,内存占用大幅降低
  • 计算速度:利用Numpy向量化运算替代循环内的逐行计算,数据量越大,效率提升越明显(比如数据量达到万级时,耗时可能仅为原方法的1/10甚至更低)
  • 逻辑清晰:将移位、计算、索引查找拆分为独立步骤,便于维护和扩展

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 23:15:53