【问题标题】:Cumulative sum with missing categories in pandas熊猫中缺失类别的累积和
【发布时间】:2013-10-08 08:00:46
【问题描述】:

假设我有以下数据集

df_dict = ({'unit' : [1, 1, 1, 2, 2, 2], 'cat' : [1, 2, 3, 1, 2, 4], 
           'count' : [8, 3, 2, 2, 8, 7] })
df = pd.DataFrame(df_dict)

df.set_index('unit', inplace = True)

看起来像这样:

    cat count
unit        
1    1   8
1    2   3
1    3   2
2    1   2
2    2   8
2    4   7

计数给出了在一个单元中观察到不同类别的频率。 我想得到的是每个单元四个类别的累积频率。请注意,第 1 单元缺少第 4 类,第 2 单元缺少第 3 类。

因此,最终结果将是

对于单元 1:

[8/13, 11/13, 13/13, 13/13]

对于第 2 单元:

[2/17, 10/17, 10/17, 17/17]

我知道如何使用groupbycumsum 获得累积和,但是例如,单元 1 没有缺失类别 4 的值。

感谢您的宝贵时间!

【问题讨论】:

    标签: python pandas


    【解决方案1】:
    import pandas as pd
    
    
    df_dict = ({'unit' : [1, 1, 1, 2, 2, 2], 'cat' : [1, 2, 3, 1, 2, 4], 
               'count' : [8, 3, 2, 2, 8, 7] })
    df = pd.DataFrame(df_dict)
    
    df.set_index('unit', inplace = True)    
    
    cumsum_count = df.groupby(level=0).apply(lambda x: pd.Series(x['count'].cumsum().values, index=x['cat']))
    # unit  cat
    # 1     1       8
    #       2      11
    #       3      13
    # 2     1       2
    #       2      10
    #       4      17
    # dtype: int64
    
    cumsum_count = cumsum_count.unstack(level=1).fillna(method='ffill', axis=1)
    # cat   1   2   3   4
    # unit               
    # 1     8  11  13  13
    # 2     2  10  10  17
    
    totals = df.groupby(level=0)['count'].sum()
    # unit
    # 1       13
    # 2       17
    # Name: count, dtype: int64
    
    cumsum_dist = cumsum_count.div(totals, axis=0)
    print(cumsum_dist)
    

    产量

    cat          1         2         3  4
    unit                                 
    1     0.615385  0.846154  1.000000  1
    2     0.117647  0.588235  0.588235  1
    

    我真的不知道如何解释这个解决方案——可能是因为我有点意外地得到了它。灵感 来自Jeff's solution,它使用了

    s.apply(lambda x: pd.Series(1, index=x))
    

    将值与索引相关联。一旦您关联了累积计数(),例如[8,11,13],带有cat 数字(index),例如[1,2,3],你基本上是免费的。其余的只是unstackfillnadivgroupby 的标准应用程序。

    【讨论】:

    • 谢谢,非常好的解决方案!!我仍然需要围绕与索引相关的值来思考......一个快速的问题:为什么你需要在 cumsum().values 中使用 .values ?我不明白这是在做什么。
    • lambda函数内部,x是一个DataFrame。 x['count'].cumsum() 是一个系列。该系列有自己的索引,我想用x['cat'] 替换它。如果我们使用pd.Series(x['count'].cumsum(), index=x['cat']),则会引发ValueError: cannot reindex ... 异常,因为原始系列在其索引中有重复条目——因此不清楚如何从旧索引映射到新索引。每个系列都有一个values 属性,它将基础数据作为 NumPy 数组返回。我们关心的是数据,而不是原始索引,所以我使用.values 来挑选数据。
    猜你喜欢
    • 2019-07-26
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多