Примените несколько агрегатных функций в списке без использования панд

#python #list #numpy #group-by #itertools

Вопрос:

У меня есть список строк с двумя ключевыми столбцами и 6 столбцами значений. Я хочу рассчитать сумму, среднее значение и максимальное значение столбцов значений на основе списков столбцов для каждой функции, сгруппированных по ключевым столбцам, с использованием itertools.groupby , без использования панд.

 columns = [ID, date, row1, row2, row3, row4, row5, row6]
rows = [[1, date1, 1,     1,    1,   0,    0,  1],
        [1, date1, 1,     2,    0,   1,    0,  1],
        [2, date1, 1,     3,    0,   0,    1,  1], 
        [2, date1, 1,     3,    0,   0,    2,  1]]

ColSum = [row2, row6]
ColMean = [row1, row3]
ColMax = [row4, row5]
 

Результат, который я ожидаю рассчитать:

 rows_result = [[1, date1, 1,     3,  0.5,   1,    0,  2],
               [2, date1, 1,     6,    0,   0,    2,  2]] 
 

Мой код:

 for cols in ColSum:
  index = int(np.where(columns == cols)[0][0])
        
  for k, g in itertools.groupby(rows[:, index], operator.itemgetter(0,1)):
    res.append((list(k)  list(map(sum, zip(*[c[2:] for c in g])))))

for colm in colMean:
  index = int(np.where(columns == colm)[0][0])
    
  for k, g in itertools.groupby(rows[:, index], operator.itemgetter(0,1)):
    res.append((list(k)  list(map(sum, zip(*[c[2:] for c in g])))))
 

Однако это не работает.

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

1. Не уверен, чего вы хотите от себя, например ColSum = [row2, row6] .

Ответ №1:

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

Вместо этого приведенная ниже программа использует ColFun для задания функции, которая будет применяться к каждому из столбцов (эквивалентно строкам с 1 по 6). В for цикле он проходит через каждую из групп (например (1, 'date1') ), создавая список из 6 столбцов значений с приложением запрашиваемой функции в столбце.

Результат добавляется в список, который соответствует (слегка отредактированному) желаемому результату.

 import itertools
import operator
import numpy as np

columns = ['ID', 'date', 'row1', 'row2', 'row3', 'row4', 'row5', 'row6']
rows = [[1, 'date1', 1,     1,    1,   0,    0,  1],
        [1, 'date1', 1,     2,    0,   1,    0,  1],
        [2, 'date1', 1,     3,    0,   0,    1,  1], 
        [2, 'date1', 1,     3,    0,   0,    2,  1]]

ColSum = ['row2', 'row6']
ColMean = ['row1', 'row3']
ColMax = ['row4', 'row5']
ColFun = [np.mean, np.sum, np.mean, np.max, np.max, np.sum]
rows_result = [[1, 'date1', 1.0,   3,  0.5,   1,    0,  2],
               [2, 'date1', 1.0,   6,  0.0,   0,    2,  2]]

res = []
for k,g in itertools.groupby(rows, operator.itemgetter(0,1)):
    res.append(list(k)   [sum(map(z[0], z[1:])) for z in
        zip(ColFun, zip(*[c[2:] for c in g]))]
        )
print(res == rows_result)
# True
print(res)
# [[1, 'date1', 1.0, 3, 0.5, 1, 0, 2],
#  [2, 'date1', 1.0, 6, 0.0, 0, 2, 2]]
 

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

1. Спасибо, мне нравится этот ответ, он мне очень помог.