如何计算pandas pivot_table的计数

时间:2017-08-03 14:39:21

标签: python pandas pivot-table

我有类似这样的数据

import random
import pandas as pd

jobs = ['Agriculture', 'Crafts', 'Labor', 'Professional']

df = pd.DataFrame({
    'JobCategory':[random.choice(jobs) for i in range(300)],
    'Region':[random.randint(1,5) for i in range(300)],
    'MaritalStatus':[random.choice(['Not Married', 'Married']) for i in range(300)]
})

我想要一个简单的表格,显示每个地区的工作数量。

print(pd.pivot_table(df,
           index='JobCategory',
           columns='Region',
           margins=True,
           aggfunc=len))

输出

             MaritalStatus                               
Region                   1     2     3     4     5    All
JobCategory                                              
Agriculture           13.0  23.0  17.0  18.0   8.0   79.0
Crafts                16.0  13.0  18.0  19.0  14.0   80.0
Labor                 15.0  11.0  19.0  11.0  14.0   70.0
Professional          22.0  17.0  16.0   7.0   9.0   71.0
All                   66.0  64.0  70.0  55.0  45.0  300.0

我假设" MaritalStatus"正在输出中显示,因为这是计算计数的列。如何根据Region-JobCategory计数让Pandas计算并忽略数据框中的无关列?

在编辑中添加---

我正在寻找一个可以输出保证金值的表格。表I中显示的值是我想要的,但我不希望MaritalStatus成为计算值。如果该列中有Nan,例如将列定义更改为

'MaritalStatus':[random.choice(['Not Married', 'Married'])
                 for i in range(299)].append(np.NaN)

这是输出(有和没有values = 'MaritalStatus',

             MaritalStatus                             
Region                   1     2     3     4     5  All
JobCategory                                            
Agriculture           16.0  14.0  16.0  14.0  16.0  NaN
Crafts                25.0  17.0  15.0  14.0  16.0  NaN
Labor                 14.0  16.0   8.0  17.0  15.0  NaN
Professional          13.0  14.0  14.0  13.0  13.0  NaN
All                    NaN   NaN   NaN   NaN   NaN  0.0

4 个答案:

答案 0 :(得分:2)

你可以用0填充nan值,然后找到len,即

df = pd.DataFrame({
'JobCategory':[random.choice(jobs) for i in range(300)],
'Region':[random.randint(1,5) for i in range(300)],
'MaritalStatus':[random.choice(['Not Married', 'Married']) for i in range(299)].append(np.NaN)})

df = df.fillna(0)
print(pd.pivot_table(df,
       index='JobCategory',
       columns='Region',
       margins=True,
       values='MaritalStatus',
       aggfunc=len))

输出:

                          
Region                   1     2     3     4     5    All
JobCategory                                              
Agriculture           19.0  17.0  13.0  20.0   9.0   78.0
Crafts                17.0  14.0   9.0  11.0  16.0   67.0
Labor                 10.0  17.0  15.0  19.0  11.0   72.0
Professional          11.0  14.0  19.0  19.0  20.0   83.0
All                   57.0  62.0  56.0  69.0  56.0  300.0

答案 1 :(得分:0)

len聚合函数计算值MaritalStatus沿JobCategory - Region的特定组合出现的次数。因此,您正在计算JobCategory - Region个实例的数量,这正是您所期望的。

答案 2 :(得分:0)

修改

我们可以为每个记录分配键值,并计算或调整该值。

df = pd.DataFrame({
'JobCategory':[random.choice(jobs) for i in range(300)],
'Region':[random.randint(1,5) for i in range(300)],
'MaritalStatus':[random.choice(['Not Married', 'Married']) for i in range(299)].append(np.NaN)})

print(pd.pivot_table(df.assign(key=1),
           index='JobCategory',
           columns='Region',
           margins=True,
           aggfunc=len,
           values='key'))

输出:

Region           1     2     3     4     5    All
JobCategory                                      
Agriculture   16.0  14.0  13.0  16.0  16.0   75.0
Crafts        14.0   9.0  17.0  22.0  13.0   75.0
Labor         11.0  18.0  20.0  10.0  16.0   75.0
Professional  16.0  14.0  15.0  14.0  16.0   75.0
All           57.0  55.0  65.0  62.0  61.0  300.0

您可以将MaritalStatus添加为values参数,这将消除列索引中的额外级别。使用aggfunc = len,你选择什么作为值参数并不重要,它将为该聚合中的每一行返回1的计数。

所以,试试:

print(pd.pivot_table(df,
           index='JobCategory',
           columns='Region',
           margins=True,
           aggfunc=len,
           values='MaritalStatus'))

输出:

Region           1     2     3     4     5    All
JobCategory                                      
Agriculture   10.0  18.0  10.0  15.0  19.0   72.0
Crafts        11.0  13.0  17.0  11.0  22.0   74.0
Labor         12.0  10.0  18.0  16.0  12.0   68.0
Professional  21.0  16.0  20.0  13.0  16.0   86.0
All           54.0  57.0  65.0  55.0  69.0  300.0

选项2

使用groupbysize

df.groupby(['JobCategory','Region']).size()

输出:

JobCategory   Region
Agriculture   1         10
              2         18
              3         10
              4         15
              5         19
Crafts        1         11
              2         13
              3         17
              4         11
              5         22
Labor         1         12
              2         10
              3         18
              4         16
              5         12
Professional  1         21
              2         16
              3         20
              4         13
              5         16
dtype: int64

答案 3 :(得分:0)

如果将数据帧缩减为最终索引计数行的一部分,则无需引用另一列即可。

pd.pivot_table(testdata[['JobCategory', 'Region']],
               index='JobCategory',
               columns='Region',
               margins=True,
               aggfunc=len)

除了“MaritialStatus”的行不存在外,输出与问题相同。