l oop над столбцом с лямбдой и вычислить по значениям из другого столбца - PullRequest
0 голосов
/ 05 марта 2020

Привет У меня есть следующий кадр данных

import pandas as pd
d = {'col1': [0.02,0.12,-0.1,0-0.07,0.01]}
df = pd.DataFrame(data=d)

df['new'] = ''
df['new'].iloc[0] = 100

df

Я пытался вычислить (начиная с строки 1) в столбце «новое» предыдущее значение, деленное на значение «col1» + 1.

Например, в первой строке, новый столбец: 100 / (0,12 + 1) = 89 285

Например, во второй строке, новый столбец: 89 285 / (- 0,10 + 1) = 99 206 и т. Д.

Я уже пытался использовать лямбда-функцию - безуспешно. Спасибо за помощь

Ответы [ 3 ]

2 голосов
/ 05 марта 2020

Попробуйте:

df['new'].iloc[0] = 100

for i in range(1,df.shape[0]):
    prev = df['new'].iloc[i-1]
    df['new'].iloc[i] = prev/(df['col1'].iloc[i]+1)

Вывод:

col1        new
-------------------
0   0.02    100
1   0.12    89.2857
2   -0.10   99.2063
3   -0.07   106.673
4   0.01    105.617
2 голосов
/ 05 марта 2020

Я думаю, numba - это способ работы с циклами, если важна производительность:

from numba import jit

d = {'col1': [0.02,0.12,-0.1,0-0.07,0.01]}
df = pd.DataFrame(data=d)

df.loc[0, 'new'] = 100

@jit(nopython=True)
def f(a, b):
    for i in range(1, a.shape[0]):
        a[i] = a[i-1] / (b[i] +1)
    return a

df['new'] = f(df['new'].to_numpy(), df['col1'].to_numpy())
print (df)
   col1         new
0  0.02  100.000000
1  0.12   89.285714
2 -0.10   99.206349
3 -0.07  106.673494
4  0.01  105.617321

Производительность для 5000 строк:

d = {'col1': [0.02,0.12,-0.1,0-0.07,0.01]}
df = pd.DataFrame(data=d)
df = pd.concat([df] * 1000, ignore_index=True)

In [168]: %timeit df['new'] = f(df['new'].to_numpy(), df['col1'].to_numpy())
277 µs ± 11.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [169]: %%timeit
     ...: for i in range(1,df.shape[0]):
     ...:     prev = df['new'].iloc[i-1]
     ...:     df['new'].iloc[i] = prev/(df['col1'].iloc[i]+1)
     ...:     
1.31 s ± 20.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [170]: %%timeit
     ...: for i_row, row in df.iloc[1:, ].iterrows():
     ...:     df.loc[i_row, 'new'] = df.loc[i_row - 1, 'new'] / (row['col1'] + 1)
     ...:     
2.08 s ± 93.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
0 голосов
/ 05 марта 2020

Я не вижу ни одного векторизованного решения. Вот такая вот л oop:

df['new'] = 100
for i_row, row in df.iloc[1:, ].iterrows():
    df.loc[i_row, 'new'] = df.loc[i_row - 1, 'new'] / (row['col1'] + 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...