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

2024-09-30 12:32:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试修改pandas数据帧,以便在每一行中,SdLog列和Meanlog列得到更新,直到第三列,std小于std_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

Tags: 数据pandasindexnploadsfmeanloc
2条回答

这是我(在样本上)测试的内容:

    frame['logic']= frame['std']>(frame['std_o']/2)
    frame['Sdlog'] = np.where(frame['logic'], frame['Sdlog']-0.0001, frame['Sdlog'])
    frame["Meanlog"] = np.where(frame['logic'],frame['Meanlog'] + (frame['Sdlog']**2)/2 - (frame['Sdlog']**2)/2 , frame['Meanlog'])
    frame['std'] = np.where(frame['logic'], ((np.exp((frame['Sdlog']**2))-1)*(np.exp(2*(frame['Meanlog'])+((frame['Sdlog'])**2))))**(.5), frame['std'])


result per 1000 iterations: 2.7607345581054688s
#original

    for index, row in frame.iterrows():
        while frame.loc[index,'std'] > row['std_o']/2:
            z = row['Sdlog'] 
            frame.loc[index, "Sdlog"] = row['Sdlog'] - 0.0001
            frame.loc[index, "Meanlog"] = row['Meanlog'] + (z**2)/2 - (row['Sdlog']**2)/2 
            frame.loc[index, "std"] = ((np.exp((row['Sdlog']**2))-1)*(np.exp(2*(row['Meanlog'])+((row['Sdlog'])**2))))**(.5)


result per 1000 iterations: >60s, interrupted. 

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

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

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来进一步加速它

相关问题 更多 >

    热门问题