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
相关产品推荐
相关产品推荐

