python - Pandas 群by : counting rows satisfying condition on other columns?

标签 python pandas group-by pandas-groupby

我想在pandas中进行groupby作为结果,获得一个数据框,其中包含用于groupby的列,每个组的元素数量以及其中的元素数量它们、每组中的元素数量、基于另一列值满足/不满足条件的元素数量。

例如这样的输入:

type    success
A       True
B       False
A       False
C       True

我想要这样的东西:

type    total    numOfSuccess numOfFailure
A       2        1             1
B       1        0             1
C       1        1             0

在 pyspark 中我这样做了

import pyspark.sql.functions as F
df = df.groupBy("type").agg(\
    F.count('*').alias('total'), \
    F.sum(F.when(F.col('success')=="true", 1).otherwise(0)).alias('numOfSuccess'),
    F.sum(F.when(F.col('success')!="true", 1).otherwise(0)).alias('numOfFails'))

在 pandas 中我只能得到 totalnumOfSuccess 为:

df_new = df.groupby(['type'], as_index=False)['success'].agg({'total':'count', 'numOfSuccess':'sum'})

或仅总计:

df = df.groupby(['type']).size().reset_index(name='NumOfReqs')

但我无法获得第三列numOfFailures,而且如果有替代方案而不是对 bool 值求和,那就更好了,因为在我看来,in可以扩展到其他情况也更容易.

我怎样才能做到这一点?

最佳答案

使用groupbyGroupBy.size为了计算所有数据,然后对于每个类别的计数需要旋转 - 使用 GroupBy.sizeunstack , crosstabpivot_table :

df1 = df.groupby('type').size().reset_index(name='count')
df2 = (df.groupby(['type', 'success']).size().unstack(fill_value=0)
        .rename(columns={True:'numOfSuccess', False:'numOfFails'}))

df2 的替代方案:

df2 = pd.crosstab(df['type'], df['success'])
        .rename(columns={True:'numOfSuccess', False:'numOfFails'}))

或者:

df2 = (df.pivot_table(index='type', columns='success', fill_value=0, aggfunc='size')
        .rename(columns={True:'numOfSuccess', False:'numOfFails'}))

df_new = df1.join(df2, on='type')
print (df_new)
  type  count  numOfFails  numOfSuccess
0    A      2           1             1
1    B      1           1             0
2    C      1           0             1

另一个解决方案是在 crosstab 中使用参数 margins并通过使用 iloc 进行索引来删除最后一行:

df = (pd.crosstab(df['type'], df['success'], margins=True)
        .rename(columns={True:'numOfSuccess', False:'numOfFails', 'All':'count'})
        .iloc[:-1]
        .reset_index()
        .rename_axis(None, axis=1))

print (df)
  type  numOfFails  numOfSuccess  count
0    A           1             1      2
1    B           1             0      1
2    C           0             1      1

编辑:如果可能 TrueFalse 不存在,请添加 reindex添加缺失的列:

print (df)
  type  success
0    A     True
1    B     True
2    A     True
3    C     True

df1 = df.groupby('type').size().reset_index(name='count')
df2 = (df.groupby(['type', 'success']).size().unstack(fill_value=0)
         .reindex(columns=[True, False], fill_value=0)
         .rename(columns={True:'numOfSuccess', False:'numOfFails'}))


df_new = df1.join(df2, on='type')
print (df_new)
  type  count  numOfSuccess  numOfFails
0    A      2             2           0
1    B      1             1           0
2    C      1             1           0

关于python - Pandas 群by : counting rows satisfying condition on other columns?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54307039/

相关文章:

python - 当脚本可以从不同位置调用时,如何编写导入语句?

python - pandas 数据格式保存 DateTimeIndex

python - 从 pandas 数据框中的字符串中删除特定 url

python-3.x - 如何在 Pandas 数据帧上迭代 TfidfVectorizer()

python - 使用 TensorFlow 作为后端的 keras 出现错误

python - Tensorflow 与 Numpy 数学函数

sql - "HAVING ... GROUP BY"和 "GROUP BY ... HAVING"之间的区别

sql - PostgreSQL 在发送参数时要求 'group by' 子句

Mysql从一系列中选择不同的值

python - Fisher在Python中的线性判别式