Возврат агрегированного кадра данных из pandas groupby

Я пытаюсь обернуть голову вокруг методов Pandas groupby. Я хотел бы написать функцию, которая выполняет некоторые функции агрегации, а затем возвращает Pandas DataFrame. Здесь представлен упрощенный пример с использованием sum(). Я знаю, что есть простые способы делать простые суммы, в реальной жизни моя функция сложнее:

import pandas as pd
df = pd.DataFrame({'col1': ['A', 'A', 'B', 'B'], 'col2':[1.0, 2, 3, 4]})

In [3]: df
Out[3]: 
  col1  col2
0    A     1
1    A     2
2    B     3
3    B     4

def func2(df):
    dfout = pd.DataFrame({ 'col1' : df['col1'].unique() ,
                           'someData': sum(df['col2']) })
    return  dfout

t = df.groupby('col1').apply(func2)

In [6]: t
Out[6]: 
       col1  someData
col1                 
A    0    A         3
B    0    B         7

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

В моем приложении для реальной жизни я группирую более одного столбца и действительно хотел бы вернуть DataFrame, а не объект Series.
Любые идеи для решения или объяснения того, что делает Pandas в моем примере выше?

----- добавлена ​​информация -----

Я должен был начать с этого примера, я думаю:

In [13]: import pandas as pd

In [14]: df = pd.DataFrame({'col1':['A','A','A','B','B','B'], 'col2':['C','D','D','D','C','C'], 'col3':[.1,.2,.4,.6,.8,1]})

In [15]: df
Out[15]: 
  col1 col2  col3
0    A    C   0.1
1    A    D   0.2
2    A    D   0.4
3    B    D   0.6
4    B    C   0.8
5    B    C   1.0

In [16]: def func3(df):
   ....:         dfout =  sum(df['col3']**2)
   ....:         return  dfout
   ....: 

In [17]: t = df.groupby(['col1', 'col2']).apply(func3)

In [18]: t
Out[18]: 
col1  col2
A     C       0.01
      D       0.20
B     C       1.64
      D       0.36

В приведенной выше иллюстрации результатом функции apply() является серия Pandas. И ему не хватает столбцов groupby из df.groupby. Суть того, с чем я борюсь, - это как создать функцию, которую я применяю к группе, которая возвращает как результат функции AND, так и столбцы, на которых она была сгруппирована?

----- еще одно обновление ------

Похоже, что если я сделаю это:

 pd.DataFrame(t).reset_index()

Я возвращаю DataFrame, который действительно близок к тому, что я был после.

Ответы

Ответ 1

Причина, по которой вы видите столбцы с 0, состоит в том, что вывод .unique() представляет собой массив .

Лучший способ понять, как будет работать ваш прием, - проверить каждую группу действий:

In [11] :g = df.groupby('col1')

In [12]: g.get_group('A')
Out[12]: 
  col1  col2
0    A     1
1    A     2

In [13]: g.get_group('A')['col1'].unique()
Out[13]: array([A], dtype=object)

In [14]: sum(g.get_group('A')['col2'])
Out[14]: 3.0

В большинстве случаев вы хотите, чтобы это было агрегированное значение .

Вывод grouped.apply всегда будет иметь метки группы как индекс (уникальные значения "col1" ), поэтому ваша примерная конструкция col1 кажется мне немного тупой.

Примечание. Чтобы поместить 'col1' (индекс) обратно в столбец, вы можете вызвать reset_index, поэтому в этом случае.

In [15]: g.sum().reset_index()
Out[15]: 
  col1  col2
0    A     3
1    B     7