Группа по совокупным элементам пока в одной группе — Pandas

#python #pandas #dataframe #group-by #pandas-groupby

Вопрос:

Вот пример того, как должен выглядеть результат:

Фрейм данных: df с требуемым выводом

 class_id    item    req_output
a           1       [1] 
a           2       [1,2]   
a           3       [1,2,3]
b           1       [1] 
b           2       [1,2]
 

Я пробовал:
df.groupby("class").apply(lambda x: list(x["item"])

 class_id    output
a           [1,2,3]
b           [1,2]

 

но это дает только всю агрегацию, однако мне нужно, чтобы агрегация происходила в каждой строке с учетом класса

Ответ №1:

Во-первых, сделайте каждый элемент списком размером 1. Здесь мы (злоупотребляем злоупотреблением?) факт [1] [2] = [1, 2] . Затем группировать по и GroupBy.apply Series.cumsum .

 df["req_output"] = (
    df["item"]
    .map(lambda x: [x])
    .groupby(df["class_id"])
    .apply(lambda x: x.cumsum())
)

  class_id  item req_output
0        a     1        [1]
1        a     2     [1, 2]
2        a     3  [1, 2, 3]
3        b     1        [1]
4        b     2     [1, 2]
 

Или мы можем создать функцию для возврата нужного списка и использования GroupBy.transform .

 def get_slices(s):
    """
    >>> get_slices( pd.Series([1, 2, 3]) )
    [[1], [1, 2], [1, 2, 3]]
    """
    lst = s.tolist()
    return [lst[:i] for i in range(1, len(lst) 1)]

df['req_output'] = df.groupby('class_id')['item'].transform(get_slices)
 

Комментарии:

1. использование? больше похоже на злоупотребление? : grin: это прекрасное злоупотребление

2. @sammywemmy ха-ха, это наверняка злоупотребление: P Спасибо, Сэмми.