#python #pandas #dataframe
#python #pandas #фрейм данных
Вопрос:
Я пытаюсь заполнить столбец предыдущим числом строк N в сгруппированном фрейме данных с использованием pandas.
Вот что у меня есть на данный момент, и это результат.
d = {'date': ['2019-01-01', '2019-02-01', '2019-03-01', '2019-02-01', '2019-03-01', '2019-01-01', '2019-03-01', '2019-01-01', '2019-02-01'],
'group': ['group_a', 'group_b', 'group_c', 'group_a', 'group_b', 'group_c', 'group_a', 'group_b', 'group_c'],
'description': ['desc_a', 'desc_b', 'desc_c', 'desc_a', 'desc_b', 'desc_c', 'desc_a', 'desc_b', 'desc_c'],
'quantity': [1, 2, 3, 2, 3, 1, 3, 1, 1]}
df = pd.DataFrame(data=d)
df["date"] = pd.to_datetime(df['date']).dt.date
df = df.sort_values('date', ascending=True, ignore_index=True)
df['pct_chg'] = (df.groupby(['group', 'description'])['quantity'].apply(pd.Series.pct_change) 1)
df['values'] = 0
df.groupby(['group', 'description', 'date', 'quantity'])['quantity'].agg(values = lambda x: x.iloc[0:1].tolist())
Текущий вывод
values
group description date quantity
group_a desc_a 2019-01-01 1 [1]
2019-02-01 2 [2]
2019-03-01 3 [3]
group_b desc_b 2019-01-01 1 [1]
2019-02-01 2 [2]
2019-03-01 3 [3]
group_c desc_c 2019-01-01 1 [1]
2019-02-01 1 [1]
2019-03-01 3 [3]
Желаемый результат
group description date quantity pct_chg values
group_a desc_a 2019-01-01 1 0.0 [1]
2019-02-01 2 2.0 [1,2]
2019-03-01 3 1.5 [1,2,3]
group_b desc_b 2019-01-01 1 0.0 [1]
2019-02-01 2 2.0 [1,2]
2019-03-01 3 1.5 [1,2,3]
group_c desc_c 2019-01-01 1 0.0 [1]
2019-02-01 1 1.0 [1,1]
2019-03-01 3 3.0 [1,1,3]
Ответ №1:
Вот мое мнение после этого фрагмента кода
df = pd.DataFrame(data=d)
df["date"] = pd.to_datetime(df['date']).dt.date
Сортируйте ['group','description','date']
, затем группируйте ["group","description"]
и сохраняйте как переменную, затем вычисляйте pct_change, а затем с помощью перечислителя в каждой группе возвращайте значения до этого окна, используя перечислитель в качестве индекса
u = df.sort_values(['group','description','date'])
g = u.groupby(["group","description"],sort=False)['quantity']
u = u.assign(pct_chg = g.pct_change().add(1).fillna(0),
values= g.transform(lambda x: [list(x[:e 1]) for e,i in enumerate(x)]))
print(u)
date group description quantity pct_chg values
0 2019-01-01 group_a desc_a 1 0.0 [1]
3 2019-02-01 group_a desc_a 2 2.0 [1, 2]
6 2019-03-01 group_a desc_a 3 1.5 [1, 2, 3]
7 2019-01-01 group_b desc_b 1 0.0 [1]
1 2019-02-01 group_b desc_b 2 2.0 [1, 2]
4 2019-03-01 group_b desc_b 3 1.5 [1, 2, 3]
5 2019-01-01 group_c desc_c 1 0.0 [1]
8 2019-02-01 group_c desc_c 1 1.0 [1, 1]
2 2019-03-01 group_c desc_c 3 3.0 [1, 1, 3]
Комментарии:
1. перегруппируйте их ^ _^ это последний и самый простой шаг
2. 🙂 Я оставлю это для OP. Закрыл мой компьютер на сегодня, поздно вечером. Спасибо за указатель. 😊
Ответ №2:
Я сделал все возможное, но последняя часть была немного сложной для меня.
grouped = df.groupby(["group","description","date"],as_index=False)["quantity"].sum()
grouped["pct_change"] = grouped.groupby("group",as_index=False)["quantity"].pct_change() 1
grouped["pct_change"].fillna(0,inplace=True)
grouped.groupby(["group","description","date"])[["quantity","pct_change"]].agg(lambda x: x)
quantity pct_change
group description date
group_a desc_a 2019-01-01 1 0.0
2019-02-01 2 2.0
2019-03-01 3 1.5
group_b desc_b 2019-01-01 1 0.0
2019-02-01 2 2.0
2019-03-01 3 1.5
group_c desc_c 2019-01-01 1 0.0
2019-02-01 1 1.0
2019-03-01 3 3.0