Как агрегировать по столбцам в пандах? - PullRequest
0 голосов
/ 17 октября 2018

Есть 5 членов, вносящих ценность чего-то для каждого [E, M, S], как показано ниже:

E,M,S,Mem1,Mem2,Mem3,Mem4,Mem5
1,365,-10,15,21,18,16,,
1,365,10,23,34,,45,65
365,365,-20,34,45,43,32,23
365,365,20,56,45,,32,38
730,365,-5,82,64,13,63,27
730,365,15,24,68,,79,78

Обратите внимание, что есть пропущенные вклады ,,.Я хочу знать количество вкладов для каждого [E, M, S].Для этого, например, вывод:

1,365,-10,4
1,365,10,4
365,365,-20,5
365,365,20,4
730,365,-5,5
730,365,15,4

groupingBy ['E', 'M', 'S'], а затем агрегирование (подсчет) или применение (функция), но по оси = 1 будетдо. Как это сделать?Или какой-то другой идиоматический способ сделать это?

1 Ответ

0 голосов
/ 17 октября 2018

Ответ, опубликованный @Wen, блестящий и, безусловно, кажется, что это самый простой способ сделать это.

Если вам нужен другой способ сделать это, вы можете использовать .melt для просмотра групп вDF.Затем используйте groupby с агрегацией .sum() в каждой группе в расплавленном DF.Вам просто нужно игнорировать NaN s при агрегировании, и один из способов сделать это - следовать подходу, описанному в этом SO post - .notnull(), примененном к группам.

ВводDF

print df
     E    M   S  Mem1  Mem2  Mem3  Mem4  Mem5
0    1  365 -10    15    21  18.0    16   NaN
1    1  365  10    23    34   NaN    45  65.0
2  365  365 -20    34    45  43.0    32  23.0
3  365  365  20    56    45   NaN    32  38.0
4  730  365  -5    82    64  13.0    63  27.0
5  730  365  15    24    68   NaN    79  78.0

Вот подход

# Apply melt to view groups
dfm = pd.melt(df, id_vars=['E','M','S'])
print(dfm.head(10))
     E    M   S variable  value
0    1  365 -10     Mem1   15.0
1    1  365  10     Mem1   23.0
2  365  365 -20     Mem1   34.0
3  365  365  20     Mem1   56.0
4  730  365  -5     Mem1   82.0
5  730  365  15     Mem1   24.0
6    1  365 -10     Mem2   21.0
7    1  365  10     Mem2   34.0
8  365  365 -20     Mem2   45.0
9  365  365  20     Mem2   45.0

# GROUP BY
grouped = dfm.groupby(['E','M','S'])

# Aggregate within each group, while ignoring NaNs
gtotals = grouped['value'].apply(lambda x: x.notnull().sum())

# (Optional) Reset grouped DF index
gtotals = gtotals.reset_index(drop=False)
print(gtotals)
     E    M   S  value
0    1  365 -10      4
1    1  365  10      4
2  365  365 -20      5
3  365  365  20      4
4  730  365  -5      5
5  730  365  15      4
...