Как я могу ускорить мой код здесь? Попытка повторить и заменить определенные значения в каждой строке. Детали в кузове - PullRequest
0 голосов
/ 04 февраля 2020

Я пытаюсь изменить кадр данных pandas так, чтобы в каждой строке обновлялись столбцы SdLog и Meanlog, пока третий столбец, std, не станет меньше половины std_o. Я вычисляю значения в пределах l oop и уменьшаю 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

Ответы [ 2 ]

1 голос
/ 04 февраля 2020

Насколько я вижу, ваш код не просто медленный, но постоянно застревает в while l oop, потому что соответствующие переменные фактически не изменяются на каждой итерации. (Значения в пределах sf изменены, но не в пределах текущего row.) Вы можете заставить его работать, переместив logi c в функцию, которую вы затем применяете к каждой строке:

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)

Это работает, но медленно. Другие могут предложить оптимизацию.

РЕДАКТИРОВАТЬ: вы можете значительно ускорить его, просто отделив математические логи c от кода, который записывает каждую строку.

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.

0 голосов
/ 04 февраля 2020

Это то, что я тестировал (на примере):

    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. 

Обратите внимание, что я работал только с небольшим образцом и не проверял, верны ли результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...