Pandas: суммирование массивов как агрегирование с несколькими столбцами groupby

#python #pandas #numpy

#python #панды #numpy

Вопрос:

Я использую Python 3.5.1 и Pandas 0.18.0.

Допустим, у меня есть фрейм данных Pandas с несколькими столбцами. Фрейм данных содержит один столбец, который включает массив numpy. Вот пример:

 >>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame([{'A': 'Label1', 'B': 'yellow', 'C': np.array([0,0,0]), 'D': 1},
                       {'A': 'Label2', 'B': 'yellow', 'C': np.array([1,1,1]), 'D': 4},
                       {'A': 'Label1', 'B': 'yellow', 'C': np.array([1,0,1]), 'D': 2},
                       {'A': 'Label2', 'B': 'green', 'C': np.array([1,1,0]), 'D': 3}])
>>> df
        A       B          C  D
0  Label1  yellow  [0, 1, 0]  1
1  Label2  yellow  [1, 1, 1]  4
2  Label1  yellow  [1, 0, 1]  2
3  Label2   green  [1, 1, 0]  3
  

Я хочу создать фрейм данных, который группируется по столбцам A и B и объединяет столбцы C и D с суммой. Вот так:

                C         D
A      B
Label1 yellow  [1, 1, 1] 3
Label2 green   [1, 1, 0] 3
       yellow  [1, 1, 1] 4
  

Когда я пытаюсь выполнить агрегацию, используя весь фрейм данных, столбец C (тот, в котором указаны массивы numpy) не возвращается:

 >>> df.groupby(['A','B']).sum()
               D
A      B
Label1 yellow  3
Label2 green   3
       yellow  4
  

Если я игнорирую столбец D и пытаюсь вывести только столбец C, я получаю сообщение об ошибке:

 >>> df[['A','B','C']].groupby(['A','B']).sum()
Traceback (most recent call last):
  File "C:Anaconda3libsite-packagespandascoregroupby.py", line 96, in f
    return self._cython_agg_general(alias, numeric_only=numeric_only)
  File "C:Anaconda3libsite-packagespandascoregroupby.py", line 3038, in _cython_agg_general
    how, numeric_only=numeric_only)
  File "C:Anaconda3libsite-packagespandascoregroupby.py", line 3084, in _cython_agg_blocks
    raise DataError('No numeric types to aggregate')
pandas.core.base.DataError: No numeric types to aggregate
  

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

 >>> df[['A','C']].groupby(['A']).sum()
                C
A
Label1  [1, 1, 1]
Label2  [2, 2, 1]
  

Но если я попытаюсь включить скалярный столбец также в качестве агрегата, мой столбец массива снова не возвращается:

 >>> df[['A','C','D']].groupby(['A']).sum()
        D
A
Label1  3
Label2  7
  

Кроме того, если я попытаюсь включить столбец B (содержит строки) в агрегатную функцию, столбцы B и C вернут, а столбец D — нет:

 >>> df[['A','B','C']].groupby(['A']).sum()
               B          C
A
Label1  yellowyellow  [1, 1, 1]
Label2   yellowgreen  [2, 2, 1]
  

Кто-нибудь может объяснить, почему это происходит? Я знаю, что мог бы создать столбец [A B], а затем сгруппировать по нему, суммировать столбец моего массива, а затем объединить полученный результат обратно с остальными моими данными в столбце [A B], но, похоже, должен быть гораздо более простой способ. Есть идеи?

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

1. «агрегирует столбцы C и D с суммой» неоднозначно. пожалуйста, покажите ожидаемый результат.

2. итак, вы знаете, df что показываемый вами не совпадает с тем, который вы создали.

3. Я изменил некоторые значения в массивах numpy, но выходные данные также должны быть обновлены.

Ответ №1:

pd.concat отдельные groupbys — это обходной путь

 g = df.groupby(['A', 'B'])
pd.concat([g.C.apply(np.sum), g.D.sum()], axis=1)
  

введите описание изображения здесь

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

1. Хорошо, я обновил вопрос, чтобы показать желаемый результат.