Pandas объединяет столбцы списка с помощью groupby при группировании по нескольким столбцам

#python #combinatorics

#python #комбинаторика

Вопрос:

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

 x = pd.DataFrame({'a':[1,1,2,2],'b':['a','a','a','b'],'c':[[1,2],[3,4],[5,6],[7,8]]})

   a  b       c
0  1  a  [1, 2]
1  1  a  [3, 4]
2  2  a  [5, 6]
3  2  b  [7, 8]
  

Теперь группировка по a или b работает так, как ожидалось:

 x.groupby('b')['c'].sum()

b
a    [1, 2, 3, 4, 5, 6]
b                [7, 8]
dtype: object

x.groupby('a')['c'].sum()

a
1    [1, 2, 3, 4]
2    [5, 6, 7, 8]
dtype: object
  

Но если я пытаюсь сгруппировать по a И b (т. Е. x.groupby(['a','b'])['c'].sum() ), это неизменно завершается неудачей с ValueError: Function does not reduce .

На первый взгляд я не понимаю, почему это должно происходить, поскольку в любом случае мы просто объединяем списки, но я полагаю, что это как-то связано с внутренними компонентами Pandas…

Какие-либо обходные пути или объяснения?

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

1. Это отлично работает, если столбец c является числовым столбцом, поэтому я предполагаю, что это связано с тем, что sum функция не понимает, что делать со списками. Иногда это будет правильно, но по какой-то причине способ, которым это вызывается во второй раз, все портит.

2. Ах, хорошая мысль. Я должен был это проверить. В любом случае, я думаю, @kabanus прав, что это, скорее всего, ошибка (если мы используем pythonic, sum должны обрабатывать списки без сбоев).

3. Определенно ошибка, но теперь мне любопытно увидеть в исходном коде, как .apply(sum) заставляет sum функцию работать со списками, в то время как .sum() этого не делает!

Ответ №1:

Я думаю, что это может быть ошибкой, когда ошибка sum не выполняется, когда некоторые строки не могут быть суммированы, например, последние две останутся разделенными при двойной группировке. Обходной путь — применить:

 import pandas as pd
x = pd.DataFrame({'a':[1,1,2,2],'b':['a','a','a','b'],'c':[[1,2],[3,4],[5,6],[7,8]]})
print x
   a  b       c
0  1  a  [1, 2]
1  1  a  [3, 4]
2  2  a  [5, 6]
3  2  b  [7, 8]
print  x.groupby(('a'))['c'].apply(sum)
a
1    [1, 2, 3, 4]
2    [5, 6, 7, 8]
Name: c, dtype: object
print x.groupby(('a'))['c'].sum()
a
1    [1, 2, 3, 4]
2    [5, 6, 7, 8]
dtype: object
print x.groupby(('a','b'))['c'].apply(sum)
a  b
1  a    [1, 2, 3, 4]
2  a          [5, 6]
   b          [7, 8]
Name: c, dtype: object
  

Я думаю, вам также следует отправить это команде pandas.