将pandas DataFrame转换为正确的格式:`DataError:没有要聚合的数字类型

时间:2017-04-17 18:18:12

标签: python pandas dataframe pivot

这是我想操作的pandas DataFrame:

import pandas as pd

data = {"grouping": ["item1", "item1", "item1", "item2", "item2", "item2", "item2", ...],
        "labels": ["A", "B", "C", "A", "B", "C", "D", ...],
        "count": [5, 1, 8, 3, 731, 189, 9, ...]}

df = pd.DataFrame(data)

print(df)
>>>   grouping            labels       count
0        item1             A            5
1        item1             B            1
2        item1             C            8
3        item2             A            3
4        item2             B          731
5        item2             C          189
6        item2             D            9
7        ...               ...         ....

我想将此数据框“展开”为以下格式:

grouping    A    B    C    D
item1       5    1    8    3
item2       3    731  189  9
....        ........

怎么会这样做?我认为这会奏效:

pd.pivot_table(df,index=["grouping", "labels"]

但是我收到以下错误:

DataError: No numeric types to aggregate

4 个答案:

答案 0 :(得分:6)

使用set_indexunstack

df = df.set_index(['grouping','labels']).unstack().rename_axis(None)
df.columns = df.columns.droplevel()
print(df)

输出:

labels  A    B    C     D
item1   5    1    8  None
item2   3  731  189     9

答案 1 :(得分:3)

您将labels放在索引中,但是您希望它在列中:

>>> df.pivot_table(index='grouping', columns='labels')
         count                   
labels       A      B      C    D
grouping                         
item1      5.0    1.0    8.0  NaN
item2      3.0  731.0  189.0  9.0

请注意,这会使列成为MultiIndex。如果您不想这样做,请明确传递valuesdf.pivot_table(index='grouping', columns='labels', values='count')

另外,请注意,只有当分组和标签的每个组合只有一个或零值时,您才会寻找重塑形式。如果任何组合出现不止一次,您需要决定如何聚合它们(例如,通过对匹配值求和)。

答案 2 :(得分:3)

有四种惯用的pandas方法可以做到这一点。

  • 分组列之间没有重复项。不需要聚合
    • pivot
    • set_index
  • 在分组列中重复。需要聚合吗?
    • pivot_table
    • groupby

pivot

df.pivot('grouping', 'labels', 'count')

set_index

df.set_index(['grouping', 'labels'])['count'].unstack()

pivot_table

df.pivot_table('count', 'grouping', 'labels')

groupby

df.groupby(['grouping', 'labels'])['count'].sum().unstack()

所有收益

labels      A      B      C    D
grouping                        
item1     5.0    1.0    8.0  NaN
item2     3.0  731.0  189.0  9.0

时间

enter image description here

使用groupbyset_indexpivot_table方法,您可以使用fill_value=0

轻松填写缺失值
df.pivot_table('count', 'grouping', 'labels', fill_value=0)

df.groupby(['grouping', 'labels'])['count'].sum().unstack(fill_value=0)

df.set_index(['grouping', 'labels'])['count'].sum().unstack(fill_value=0)

所有收益

labels    A    B    C  D
grouping                
item1     5    1    8  0
item2     3  731  189  9

关于groupby

的其他想法

因为我们不需要任何汇总。如果我们想使用groupby,我们可以通过利用影响较小的聚合器来最小化隐式聚合的影响。

df.groupby(['grouping', 'labels'])['count'].max().unstack()

df.groupby(['grouping', 'labels'])['count'].first().unstack()

时间groupby

enter image description here

答案 3 :(得分:2)

尝试:

In [1]: import pandas as pd
   ...: 
   ...: data = {"grouping": ["item1", "item1", "item1", "item2", "item2", "item2", "item2"],
   ...:         "labels": ["A", "B", "C", "A", "B", "C", "D"],
   ...:         "count": [5, 1, 8, 3, 731, 189, 9]}
   ...: 
In [2]: df = pd.DataFrame(data)
In [3]: df.pivot_table(index="grouping",columns="labels")

Out[3]: 
             count              
    labels       A    B    C   D
    grouping                    
    item1        5    1    8 NaN
    item2        3  731  189   9