Pivot a pandas DataFrame to be the correct format: `DataError: No numeric types to aggregate`

Pivot a pandas DataFrame to be the correct format: `DataError: No numeric types to aggregate`

这是我要操作的 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        ...               ...         ....

我想"unfold"将此数据帧转换为以下格式:

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

您将 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

请注意,这会使列成为多索引。如果你不想这样,显式传递 values: df.pivot_table(index='grouping', columns='labels', values='count').

另外,请注意,只有当分组和标签的每个组合都恰好有一个或零值时,您似乎正在寻找的那种重塑才有可能。如果任何组合出现不止一次,您需要决定如何聚合它们(例如,通过对匹配值求和)。

尝试:

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

使用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

有四种惯用的 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

时间

使用 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