【问题标题】:How to calculate counts on pandas pivot_table如何计算 pandas pivot_table 的计数
【发布时间】:2017-08-03 14:39:20
【问题描述】:

我有类似这样的数据

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”显示在输出中,因为这是计算计数的列。如何让 Pandas 根据 Region-JobCategory 计数进行计算并忽略数据框中的无关列?

在编辑中添加---

我正在寻找一个要输出边距值的表格。我显示的表中的值是我想要的,但我不希望 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

【问题讨论】:

    标签: python pandas pivot-table


    【解决方案1】:

    您可以用 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))
    

    输出:

    地区 1 2 3 4 5 全部 职位类别 农业 19.0 17.0 13.0 20.0 9.0 78.0 工艺品 17.0 14.0 9.0 11.0 16.0 67.0 劳动力 10.0 17.0 15.0 19.0 11.0 72.0 专业 11.0 14.0 19.0 19.0 20.0 83.0 全部 57.0 62.0 56.0 69.0 56.0 300.0

    【讨论】:

    • 不,我正在寻找一个带有边距值的表格。
    • 您可以用一些值填充 Nan,然后找到 len。希望对你有帮助
    【解决方案2】:

    如果您将数据框缩减为仅将成为最终索引计数行的一部分的列,则无需参考另一列。

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

    输出与问题中的相同,只是“MaritialStatus”行不存在。

    【讨论】:

    • 有趣——提供自己的答案,但最终没有接受
    【解决方案3】:

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

    【讨论】:

    • 不,我正在计算每个组合中 MaritalStatus 实例的数量。如果列中包含 NaN,则会出现问题。
    【解决方案4】:

    编辑

    我们可以为每条记录分配键值并计算或调整该值的大小。

    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,无论您选择什么作为 values 参数,它都会为该聚合中的每一行返回一个计数 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
    

    【讨论】:

    • 在 pivot_table 示例中,如果我使用的额外列包含 NaN,则所有边距值都是 NaN。 groupby 没有为“All”提供值,必须将其转换为表格形式。
    • 在您的问题中创建该示例。如果您不想聚合 NaN 值,请查看 size 和 len vs count 之间的差异。 Count 只计算非空值。
    • @verisimilidude 好的。请参阅编辑,我在其中为每条记录创建一个值为 1 的“键”列,然后我将该列计算为我的聚合。
    猜你喜欢
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2014-09-20
    相关资源
    最近更新 更多