【问题标题】:pandas dataframe groupby conditional count on multi-level column多级列上的熊猫数据框分组条件计数
【发布时间】:2021-11-08 09:04:07
【问题描述】:

假设我们有这样的数据框

np.random.seed(123)
df = pd.DataFrame(np.random.randint(100,size=(4, 4)),columns = pd.MultiIndex.from_product([['exp0','exp1'],['rnd0','rnd1']],names=['experiments','rnd_runs']))

df['grp1','cat'] = ['A','A','B','B']
df['grp2','cat2'] = ['C','C','C','B']

experiments exp0            exp1            grp1 grp2
rnd_runs    rnd0    rnd1    rnd0    rnd1    cat cat2
0             66    92      98      17      A   C
1             83    57      86      97      A   C
2             96    47      73      32      B   C
3             46    96      25      83      B   B

我想将('exp0', 'rdn0') 列中的count 值与groupby ('grp1','cat') 结合起来

所以我尝试了;

df['exp0_cnt','rdn0'] = df.groupby([('grp1','cat')])[('exp0', 'rdn')].apply(sum(x > 50 for x in df[(('exp0', 'rdn'))]))

但出现错误

TypeError: other 必须是 MultiIndex 或元组列表

这是类似的帖子,我想我正在使用tuples 进行多级列调用。

conditional on multi header pandas dataframe

pandas dataframe groupby on multiindex

Better way for creating columns in a multi level columns pandas dataframe

【问题讨论】:

    标签: python pandas dataframe pivot-table multi-index


    【解决方案1】:

    从 groupby 中选择 MultiIndex 列的唯一方法是使用 list 元组或 MultiIndex(如错误消息所示):

    因此,它需要是[[('exp0', 'rdn')]],而不是[('exp0', 'rdn')],然后它只需要是一个有效的列名,例如('exp0', 'rnd0')

    df['exp0_cnt', 'rdn0'] = (
        df.groupby([('grp1', 'cat')])[[('exp0', 'rnd0')]]
            #                                   ^ need to use valid column name
            #                         ^ needs to be a list of tuples
            .transform(lambda x: x.gt(50).sum())  # Some function that works
    )
    

    *我还更改了 apply 函数,因为它似乎缺少 lambda 所以我猜测了一个等效函数:

    .apply(sum(x > 50 for x in df[(('exp0', 'rdn'))])
    

    transform,因为它被分配回DataFrame:

    .transform(lambda x: x.gt(50).sum())
    

    df:

    experiments exp0      exp1      grp1 grp2 exp0_cnt
    rnd_runs    rnd0 rnd1 rnd0 rnd1  cat cat2     rdn0
    0             66   92   98   17    A    C        2
    1             83   57   86   97    A    C        2  # 2 values over 50 (in group)
    2             96   47   73   32    B    C        1
    3             46   96   25   83    B    B        1  # 1 values over 50 (in group)
    

    请注意:这意味着不能通过选择 MultiIndex 列来创建SeriesGroupBy,只能通过DataFrameGroupBy 操作来创建。

    type(df.groupby([('grp1', 'cat')])[[('exp0', 'rnd0')]])
    # <class 'pandas.core.groupby.generic.DataFrameGroupBy'>
    

    这将排除一些操作,如SeriesGroupBy.unique

    df.groupby([('grp1', 'cat')])[[('exp0', 'rnd0')]].unique()
    
    AttributeError: 'DataFrameGroupBy' object has no attribute 'unique'
    

    但是,我们可以通过从 DataFrame 中选择系列并直接按系列值分组来强制使用 SeriesGroupBy

    df[('exp0', 'rnd0')].groupby(df[('grp1', 'cat')]).unique()
    #  ^ select specific column  ^ pass the Series to groupby directly
    
    (grp1, cat)
    A    [66, 83]
    B    [96, 46]
    Name: (exp0, rnd0), dtype: object
    

    【讨论】:

    • 工作就像一个魅力。!谢谢。对不起,列名中的错误:)
    • 没问题。我知道你的意思。 :)
    猜你喜欢
    • 2017-08-21
    • 2021-12-23
    • 1970-01-01
    • 2019-02-15
    • 2020-10-14
    • 2019-05-15
    • 2022-01-12
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多