Насколько я вижу, ваш код не просто медленный, но постоянно застревает в 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
.