Python 我如何在这里加速我的代码?尝试迭代并替换每行中的某些值。正文中的细节
我正在尝试修改pandas数据帧,以便在每一行中,Python 我如何在这里加速我的代码?尝试迭代并替换每行中的某些值。正文中的细节,python,pandas,loops,dataframe,Python,Pandas,Loops,Dataframe,我正在尝试修改pandas数据帧,以便在每一行中,SdLog和Meanlog列得到更新,直到第三列,std小于std\u o的一半。我正在计算循环中的值,每次都减少sdLog,直到计算值达到50%左右 for index, row in sf.iterrows(): while sf.loc[index,'std'] > row['std_o']/2: z = row['Sdlog'] sf.loc[index, "Sdlog"] = row['Sdlog'] - 0.0
SdLog
和Meanlog
列得到更新,直到第三列,std
小于std\u o
的一半。我正在计算循环中的值,每次都减少sdLog
,直到计算值达到50%左右
for index, row in sf.iterrows():
while sf.loc[index,'std'] > row['std_o']/2:
z = row['Sdlog']
sf.loc[index, "Sdlog"] = row['Sdlog'] - 0.0001
sf.loc[index, "Meanlog"] = row['Meanlog'] + (z**2)/2 - (row['Sdlog']**2)/2
sf.loc[index, "std"] = ((np.exp((row['Sdlog']**2))-1)*(np.exp(2*(row['Meanlog'])+((row['Sdlog'])**2))))**(.5)
print(row, row['std']/row['std_o'])
这能加速吗?这条路对吗?我非常感谢您的帮助
我的数据框看起来像这样
Activity Equipment Meanlog Sdlog shiftindex actual_values std mean std_o mean_o
0 Load CF24 5.83 0.1995 364060 354.779340 69.998462 347.234380 70.147167 347.234380
1 Spot CF24 3.34 0.6100 364060 61.521021 22.820515 33.989444 22.820515 33.989444
2 Load CF24 6.33 0.1500 364070 538.410033 85.606872 567.505250 85.606872 567.505250
3 Spot CF24 3.45 0.3200 364070 24.901455 10.887160 33.155214 10.887160 33.155214
4 Load CF24 6.04 0.2500 364080 387.610354 110.019983 433.221871 110.019983 433.221871
这是我(在样本上)测试的内容:
frame['logic']=frame['std']>(frame['std_o']/2)
帧['Sdlog']=np.其中(帧['logic'],帧['Sdlog']-0.0001,帧['Sdlog'])
帧['Meanlog']=np.其中(帧['logic'],帧['Meanlog']+(帧['Sdlog']**2)/2-(帧['Sdlog']**2)/2,帧['Meanlog']
帧['std']=np.其中(帧['logic'],((np.exp((帧['Sdlog']**2))-1)*(np.exp(2*(帧['Meanlog'])+((帧['Sdlog']**2)))**(.5),帧['std']))
每1000次迭代的结果:2.7607345581054688s
#原件
对于索引,frame.iterrows()中的行:
而frame.loc[索引,'std']>行['std_o']/2:
z=行['Sdlog']
frame.loc[索引,“Sdlog”]=行['Sdlog']-0.0001
frame.loc[index,“Meanlog”]=行['Meanlog']+(z**2)/2-(行['Sdlog']**2)/2
frame.loc[index,“std”]=((np.exp((第['Sdlog'行]**2))-1)*(np.exp(第2*(第['Meanlog'行])+((第['Sdlog'行])**2))**(.5)
每1000次迭代的结果:>60s,中断。
请注意,我只使用了小样本,并没有真正检查结果是否正确。据我所知,您的代码不仅速度慢,而且在
过程中会永久卡在循环中,因为相关变量在每次迭代中实际上都没有改变。(sfsf
中的值被更改,但不在当前行中
)您可以将逻辑移动到一个函数,然后应用到每一行:
def alter(r):
while r["std"] > r["std_o"] / 2:
z = r["Sdlog"]
r["Sdlog"] = r["Sdlog"] - .0001
r["Meanlog"] = r['Meanlog'] + (z**2)/2 - (r['Sdlog']**2)/2
r["std"] = ((np.exp((r['Sdlog']**2))-1)*(np.exp(2*(r['Meanlog'])+((r['Sdlog'])**2))))**(.5)
return r
altered = sf.apply(alter, axis=1)
这是可行的,但速度很慢。其他人可能会提出优化建议
编辑:只需将数学逻辑与写入每行的代码分离,就可以大大加快速度
def alter(r):
r["std"], r["Sdlog"], r["Meanlog"] = change_std(
s=r["std"],
so=r["std_o"],
sl=r["Sdlog"],
ml=r["Meanlog"])
return r
def change_std(s, so, sl, ml):
ch = .0001
ch2 = .5 * ch * ch
s2 = s * s
target = so * so / 4
while s2 > target:
ml += ch * sl - ch2 # this simplifies ml += sl**2/2 - (sl-ch)**2/2
sl -= ch
s2 = (np.exp(sl*sl) - 1) * np.exp(2*ml + sl*sl)
return s2 ** .5, sl, ml
看看这样写的算法,我想你可以通过从一个大的ch
开始,每次超过s
的期望值大约so/2
时减少它来进一步加速它。你能在代码而不是图像中发布测试数据帧吗?如果你的代码工作得很好,试试@Kenan,我该怎么做?对不起,这里是新的!看看np.where,它应该比pandas工作得更快,因为它在一个较低的级别上:你确定你的代码可以工作吗?当我尝试它时,它似乎被卡住了,因为行['Sdlog']
和行['Meanlog']
在每次迭代中实际上都没有改变谢谢!这运行速度很快,但相当于if循环而不是while循环。与中一样,它只运行一次并终止-关于如何使其运行直到值小于一半的任何建议,而不仅仅是在@TJB不需要循环的情况下,当您构建frame[logic]时,它将包含条件分别为True或False的索引的True/False数组。np.where在单个解析中处理该数组,并在onceI处计算数组中所有元素的条件。但它仍然只运行一次。例如,当它运行时,它将Sdlog
的值更改为(-.0001),但std
仍然大于std\u o
的一半。它直到完成才更新。这有意义吗?@TJB,只要条件为假,计算就会被忽略。您的数据中是否有特定的顺序,并且希望程序在第一次遇到时停止(即使以后情况可能是真的)?@TJB,这不应该发生,np.where遍历整个数组。当然,我可能把逻辑搞乱了。它适用于样本上的整个数组。这确实有效!谢谢,很高兴知道这样做是可行的。但是正如你提到的,它非常慢。哇,谢谢你!!现在真的很好用。你是个天才。