Python Pandas进行groupby计数时出现错误

10

在对多个列进行分组计数时,我遇到了一个错误。这是我的数据框和一个简单标记不同b和c组的示例。

df = pd.DataFrame(np.random.randint(0,2,(4,4)),
                  columns=['a', 'b', 'c', 'd'])
df['gr'] = df.groupby(['b', 'c']).grouper.group_info[0]
print df
   a  b  c  d  gr
0  0  1  0  0   1
1  1  1  1  0   2
2  0  0  1  0   0
3  1  1  1  1   2

然而,当稍微改变一下示例,调用count()而不是grouper.group_info [0]时,就会出现错误。

df = pd.DataFrame(np.random.randint(0,2,(4,4)),
                  columns=['a', 'b', 'c', 'd'])
df['gr'] = df.groupby(['b', 'c']).count()
print df

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-70-a46f632214e1> in <module>()
      1 df = pd.DataFrame(np.random.randint(0,2,(4,4)),
      2                   columns=['a', 'b', 'c', 'd'])
----> 3 df['gr'] = df.groupby(['b', 'c']).count()
      4 print df

C:\Python27\lib\site-packages\pandas\core\frame.pyc in __setitem__(self, key, value)
   2036         else:
   2037             # set column
-> 2038             self._set_item(key, value)
   2039 
   2040     def _setitem_slice(self, key, value):

C:\Python27\lib\site-packages\pandas\core\frame.pyc in _set_item(self, key, value)
   2082         ensure homogeneity.
   2083         """
-> 2084         value = self._sanitize_column(key, value)
   2085         NDFrame._set_item(self, key, value)
   2086 

C:\Python27\lib\site-packages\pandas\core\frame.pyc in _sanitize_column(self, key, value)
   2110                     value = value.values.copy()
   2111                 else:
-> 2112                     value = value.reindex(self.index).values
   2113 
   2114                 if is_frame:

C:\Python27\lib\site-packages\pandas\core\frame.pyc in reindex(self, index, columns, method, level, fill_value, limit, copy)
   2527         if index is not None:
   2528             frame = frame._reindex_index(index, method, copy, level,
-> 2529                                          fill_value, limit)
   2530 
   2531         return frame

C:\Python27\lib\site-packages\pandas\core\frame.pyc in _reindex_index(self, new_index, method, copy, level, fill_value, limit)
   2606                        limit=None):
   2607         new_index, indexer = self.index.reindex(new_index, method, level,
-> 2608                                                 limit=limit)
   2609         return self._reindex_with_indexers(new_index, indexer, None, None,
   2610                                            copy, fill_value)

C:\Python27\lib\site-packages\pandas\core\index.pyc in reindex(self, target, method, level, limit)
   2181             else:
   2182                 # hopefully?
-> 2183                 target = MultiIndex.from_tuples(target)
   2184 
   2185         return target, indexer

C:\Python27\lib\site-packages\pandas\core\index.pyc in from_tuples(cls, tuples, sortorder, names)
   1803                 tuples = tuples.values
   1804 
-> 1805             arrays = list(lib.tuples_to_object_array(tuples).T)
   1806         elif isinstance(tuples, list):
   1807             arrays = list(lib.to_object_array_tuples(tuples).T)

C:\Python27\lib\site-packages\pandas\lib.pyd in pandas.lib.tuples_to_object_array (pandas\lib.c:42342)()

ValueError: Buffer dtype mismatch, expected 'Python object' but got 'long long'
1个回答

13

在交互式会话中评估 df.groupby(['b', 'c']).count()

In [150]: df.groupby(['b', 'c']).count()
Out[150]: 
     a  b  c  d
b c            
0 0  1  1  1  1
  1  1  1  1  1
1 1  2  2  2  2

这是一个完整的数据框,可能不适合分配给df的新列(事实上,您不能将列分配给数据框,这就是为什么会引发一条尽管晦涩的异常信息)。


如果您希望创建一个新列来计算每个组中的行数,可以使用以下代码:

df['gr'] = df.groupby(['b', 'c'])['a'].transform('count')
例如,
import pandas as pd
import numpy as np
np.random.seed(1)
df = pd.DataFrame(np.random.randint(0, 2, (4, 4)),
                  columns=['a', 'b', 'c', 'd'])
print(df)
#    a  b  c  d
# 0  1  1  0  0
# 1  1  1  1  1
# 2  1  0  0  1
# 3  0  1  1  0

df['gr'] = df.groupby(['b', 'c'])['a'].transform('count')

df['comp_ids'] = df.groupby(['b', 'c']).grouper.group_info[0]
print(df)
产出。
   a  b  c  d  gr  comp_ids
0  1  1  0  0   1         1
1  1  1  1  1   2         2
2  1  0  0  1   1         0
3  0  1  1  0   2         2

请注意,df.groupby(['b', 'c']).grouper.group_info[0]返回的内容并不是每个组中行数的计数,而是每个组的标签。


如果我使用 df.groupby(['b', 'c'])['a'].count() 将其转换为 Series,它仍然无法工作。另外请注意,df['gr'] = df['a']+df['b'] 是有效的,所以我不理解您关于不能将列分配给数据框的评论。 - user2464433
df['a']+df['b'] 是一个带有单层索引的Series,因此将其分配给 df['gr'] 没有问题。df.groupby(['b', 'c'])['a'].count() 是一个Series,但它具有多级索引,因此仍然不清楚如何将其分配给具有单级索引的 df['gr'] - unutbu
我喜欢在异常中的注释 # hopefully? (!),可能这是应该放在 try/except 中以获得更友好的消息。 - Andy Hayden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接