Я создал следующий фрейм данных pandas:
import pandas as pd
import numpy as np
ds = { 'trend' : [1,1,1,1,2,2,3,3,3,3,3,3,4,4,4,4,4], 'price' : [23,43,56,21,43,55,54,32,9,12,11,12,23,3,2,1,1]}
df = pd.DataFrame(data=ds)
Кадр данных выглядит следующим образом:
display(df)
trend price
0 1 23
1 1 43
2 1 56
3 1 21
4 2 43
5 2 55
6 3 54
7 3 32
8 3 9
9 3 12
10 3 11
11 3 12
12 4 23
13 4 3
14 4 2
15 4 1
16 4 1
Я сохранил фрейм данных в файле .csv с именем df.csv
:
df.to_csv("df.csv", index = False)
Мне нужно создать новое поле под названием minimum
, которое:
price
, наблюдаемым на каждой итерации, и последним price
, наблюдаемым в предыдущей trend
.Например:
Перенесемся к записи 4.
price
, наблюдаемым в записи 4 (price: 43
), и последним price
, наблюдаемым для предыдущей trend
(price: 21
). Результат: 21.Перенесемся к записи 14.
price
, наблюдаемым в записи 14 (price: 2
), и последним price
, наблюдаемым для предыдущей trend
(price: 12
). Результат 2.И так далее.
Затем я написал этот код:
minimum = []
for i in range(len(df)):
ds = pd.read_csv("df.csv", nrows=i+1)
d = ds.groupby('trend', as_index=False).agg(
{'price':'last'})
d['minimum'] = d['price'].min()
minimum.append(d['minimum'].iloc[-1])
ds['minimum'] = minimum
Результирующий фрейм данных выглядит следующим образом:
дисплей(д)
trend price minimum
0 1 23 23
1 1 43 43
2 1 56 56
3 1 21 21
4 2 43 21
5 2 55 21
6 3 54 21
7 3 32 21
8 3 9 9
9 3 12 12
10 3 11 11
11 3 12 12
12 4 23 12
13 4 3 3
14 4 2 2
15 4 1 1
16 4 1 1
Полученный фрейм данных правильный.
Проблема в том, что мне приходится применить этот процесс к фрейму данных, который содержит около 1 миллиона записей, и на его выполнение уйдет около 48 лет.
Кто-нибудь знает более быстрый способ получить те же результаты, что и выше?
просто предыдущая тенденция
Хорошо, иначе вам нужно будет добавить cummin
к prev
.
Агрегируйте, сдвиг , затем карту и получите минимум с помощью numpy:
prev = (df.groupby('trend')['price'].min()
.shift(fill_value=np.inf)
)
df['minimum'] = np.minimum(df['price'], df['trend'].map(prev))
Выход:
trend price minimum
0 1 23 23
1 1 43 43
2 1 56 56
3 1 21 21
4 2 43 21
5 2 55 21
6 3 54 43
7 3 32 32
8 3 9 9
9 3 12 12
10 3 11 11
11 3 12 12
12 4 23 9
13 4 3 3
14 4 2 2
15 4 1 1
16 4 1 1
Хотите ли вы учитывать минимум предыдущего тренда или всех предыдущих трендов?