如何计算满足特定条件的大熊猫groupby的值

时间:2020-06-09 00:54:35

标签: python pandas dataframe indexing group-by

在开始之前,我想清楚地说明我的问题与Counting values that meet a conditionWant to count the number of values in a column that meet a condition不同。

请允许我解释。这是我的df:

test = pd.DataFrame({'name':['joe','dan','betty','joe','dan','betty','joe','dan','betty','joe','dan','betty'],'points':[12,3,5,10,5,16,2,8,15,17,1,3]})
test


   name points
0   joe   12
1   dan    3
2   betty  5
3   joe   10
4   dan    5
5   betty 16
6   joe    2
7   dan    8
8   betty 15
9   joe   17
10  dan    1
11  betty  3

我的目标是计算每个人获得少于10分的次数,并创建一个包含该值的新列。我尝试了以下操作,并且非常接近:

test['<10'] = test[test['points'] < 10].groupby('name')['points'].transform('count')
test


    name    points  <10
0   joe       12    NaN
1   dan        3    4.0
2   betty      5    2.0
3   joe       10    NaN
4   dan        5    4.0
5   betty     16    NaN
6   joe        2    1.0
7   dan        8    4.0
8   betty     15    NaN
9   joe       17    NaN
10  dan        1    4.0
11  betty      3    2.0

我得到了想要的值,但是由于我将数据帧的子集设置为值<10,因此在排除的行中保留了NaN。我几乎已经弄清楚了,但是我想填充这些NaN值来显示每个人有多少次少于10分(即joe应该有1,betty 2和dan 4)。任何帮助表示赞赏,谢谢!

2 个答案:

答案 0 :(得分:2)

您的代码仅选择point < 10处的行。逻辑是您需要直接在sum的掩码上point < 10True等效于1False等于0。因此,point < 10上的总和将返回True的计数。根据这种逻辑,您只需要分组并执行transform即可将True的计数填充到每个组

test['<10'] = (test['points'] < 10).groupby(test['name']).transform('sum')

Out[84]:
     name  points  <10
0     joe      12  1.0
1     dan       3  4.0
2   betty       5  2.0
3     joe      10  1.0
4     dan       5  4.0
5   betty      16  2.0
6     joe       2  1.0
7     dan       8  4.0
8   betty      15  2.0
9     joe      17  1.0
10    dan       1  4.0
11  betty       3  2.0

答案 1 :(得分:2)

修正代码,删除transform并添加reindex

test['<10']=test[test['points'] < 10].groupby('name')['points'].count().reindex(test.name).values
test
     name  points  <10
0     joe      12    1
1     dan       3    4
2   betty       5    2
3     joe      10    1
4     dan       5    4
5   betty      16    2
6     joe       2    1
7     dan       8    4
8   betty      15    2
9     joe      17    1
10    dan       1    4
11  betty       3    2