Python 我如何在这里加速我的代码?尝试迭代并替换每行中的某些值。正文中的细节

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

我正在尝试修改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.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,中断。

请注意,我只使用了小样本,并没有真正检查结果是否正确。

据我所知,您的代码不仅速度慢,而且在
过程中会永久卡在
循环中,因为相关变量在每次迭代中实际上都没有改变。(sf
sf
中的值被更改,但不在当前
行中
)您可以将逻辑移动到一个函数,然后应用到每一行:

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遍历整个数组。当然,我可能把逻辑搞乱了。它适用于样本上的整个数组。这确实有效!谢谢,很高兴知道这样做是可行的。但是正如你提到的,它非常慢。哇,谢谢你!!现在真的很好用。你是个天才。