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

Pandas生成系统状态矩阵的效率优化方案及循环赋值性能差异疑问

Pandas生成系统状态矩阵的效率优化方案及循环赋值性能差异疑问

我想要创建一个描述系统不同时间状态的Pandas DataFrame,具体需求如下:

  • 初始状态对应第一行数据
  • 每一行对应一个时间点
  • 前两列预留用于“household”/统计信息
  • 后续列是系统状态参数
  • 每次迭代(每一行)会有若干参数发生变化,可能是一个或多个

我已经模拟出了简化版的变更数据:df_change

问题1

有没有比我当前代码更高效的生成矩阵的方式?我现在是通过循环更新状态并插入行的方式实现的。

问题2

我在写示例代码时发现了一个有趣的现象:如果把“household”列的赋值放在循环之后,循环迭代的性能会提升20倍!我使用的是Python 3.12.4和Pandas 2.2.2,这是为什么呢?

比如这段赋值代码:

df["product"] ="some_product"

下面是我的示例代码:

#%%

import numpy as np
import pandas as pd
from tqdm import tqdm
num_cols =600
n_changes = 40000


# simulate changes

extra_colums = ["n_changes","product"]
columns = [chr(i+65) for i in range(num_cols)]

state = { icol : np.random.random() for icol in columns}

change_index = np.random.randint(0,4,n_changes).cumsum()
change_col =  [columns[np.random.randint(0,num_cols)] for i in range(n_changes)]
change_val= np.random.normal(size=n_changes)

# create change matrix
df_change=pd.DataFrame(index= change_index )
df_change['col'] = change_col
df_change['val'] = change_val
index = np.unique(change_index)


# %%
# Slow approach  gives 5 iterations/s
df = pd.DataFrame(index= index, columns=extra_colums + columns)
df["product"] ="some_product"
for i in tqdm(index):
    state.update(zip(df_change.loc[[i],"col"] , df_change.loc[[i],"val"]))
    df.loc[i,columns] = pd.Series(state)

# %%
# Fast approach gives 1000 iterations/sec
df2 = pd.DataFrame(index= index, columns=extra_colums + columns)
for i in tqdm(index):
    state.update(zip(df_change.loc[[i],"col"] , df_change.loc[[i],"val"]))
    df2.loc[i,columns] = pd.Series(state)
df2["product"] ="some_product"

补充说明

我已经标记ouroboros1的回答为最佳解决方案——它非常有效,解决了问题1。

不过我仍然对问题2感到好奇:两种循环赋值方法的性能差异。我发现,根据循环前赋值方式的不同,也能得到和原“df2”方法相近的性能:

# Fast approach gives 1000 iterations/sec
df3 = pd.DataFrame(index=index, columns=extra_colums + columns)

#df3.loc[index,"product"] = "some_product" # Fast  
#df3["product"] = "some_product"           # Slow  
df3.product = "some_product"               # Fast

for i in tqdm(index):
    state.update(zip(df_change.loc[[i], "col"], df_change.loc[[i], "val"]))
    df3.loc[i, columns] = np.array(list(state.values())) 

备注:内容来源于stack exchange,提问作者user1573820

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 08:42:59