Использование pandas для groupby и выбора предыдущих N строк для размещения в списке в новом столбце

#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