Pandas“countif”基于列值和多索引

时间:2018-02-05 16:42:54

标签: python-3.x pandas group-by count

我有一个看起来像这样的DataFrame: enter image description here

我将YEARRACEETHN作为multiindex。我想计算每个列变量的每个YEARRACEETHN组合的“1”值的数量(注意,数据不仅是0和1,所以我不能做总和)。 / p>

通过这样做,我可以计算每列的值= 1:

(df_3.ACSUPPSV == 1).sum()
(df_3.PSEDSUPPSV == 1).sum()

我想用groupby执行此操作,但无法让它工作。我已经尝试了以下代码来测试我是否可以在单个列'ACSUPPSV'上执行此操作并且它不起作用:

df.groupby(['YEAR', 'RACEETHN']).loc[df.ACSUPPSV == 1, 'ACSUPPSV'].count()

我将数据导出到excel并且能够使用快速的“COUNTIF”公式计算出来,但我知道必须有一种方法可以在pandas中执行此操作 - 来自excel的结果如下所示:

enter image description here

如果有人有更好的方法来执行此操作而不是导出到Excel,我将不胜感激! :)

1 个答案:

答案 0 :(得分:2)

我认为您需要agg仅使用自定义函数进行计数1

df_3 = pd.DataFrame({'ACSUPPSV':[1,1,1,1,0,1],
                   'PSEDSUPPSV':[1,1,0,1,0,0],
                   'BUDGETSV':[1,0,1,1,1,0],
                   'YEAR':[2000,2000,2001,2000,2000,2000],
                   'RACEETHN':list('aaabbb')}).set_index(['YEAR','RACEETHN'])

print (df_3)

               ACSUPPSV  BUDGETSV  PSEDSUPPSV
YEAR RACEETHN                                
2000 a                1         1           1
     a                1         0           1
2001 a                1         1           0
2000 b                1         1           1
     b                0         1           0
     b                1         0           0

df2 = df_3.groupby(['YEAR', 'RACEETHN']).agg(lambda x: (x == 1).sum())
print (df2)
               ACSUPPSV  BUDGETSV  PSEDSUPPSV
YEAR RACEETHN                                
2000 a                2         1           2
     b                2         2           1
2001 a                1         1           0

旧答案:

df_3[((df_3.ACSUPPSV == 1) & (df_3.PSEDSUPPSV == 1))].groupby(['YEAR', 'RACEETHN']).size()

df_3.query('ACSUPPSV == 1 & PSEDSUPPSV == 1').groupby(['YEAR', 'RACEETHN']).size()

更一般:

cols = ['ACSUPPSV','PSEDSUPPSV']
df_3[(df_3[cols] == 1).all(axis=1)].groupby(['YEAR', 'RACEETHN']).size()

对于所有列:

df_3[(df_3 == 1).all(axis=1)].groupby(['YEAR', 'RACEETHN']).size()

编辑:

或者可能需要:

df_3.groupby(['YEAR', 'RACEETHN']).agg(lambda x: (x == 1).sum())