计算组内值的比例

时间:2021-02-08 10:16:01

标签: python apache-spark pyspark apache-spark-sql pyspark-dataframes

我正在尝试计算出现在子组内特定列中的特定值的比例。

示例数据框

pdf = pd.DataFrame({
    'id': [1, 1, 1, 1, 2, 2, 2, 3, 3, 3],
    'letter': ['L', 'A', 'L', 'L', 'L', 'L', 'L', 'A', 'L', 'L']
})
df = spark.createDataFrame(pdf)
df.show()

我试图依靠 this 答案,但使用以下代码

df\
    .groupby('id')\
    .agg((count(col('letter') == 'L') / count(col('letter'))).alias('prop'))\
    .show()

即使我将 1.0 更改为 'L',我也获得了一个充满 'A' 的列。

我想要的输出是,对于每个组,该组内 'L' 值的比例:

+---+--------+
| id|    prop|
+---+--------+
|  1|    0.75|
|  2|     1.0|
|  3| 0.66667|
+---+--------+

2 个答案:

答案 0 :(得分:2)

您可以将 sumwhen 一起使用来计算 L 的出现次数:

df.groupby('id')\
  .agg((F.sum(F.when(F.col('letter') == 'L', 1)) / F.count(F.col('letter'))).alias('prop'))\
  .show()

这只会给你非空值的比例。如果要对所有行进行计算,请除以 count("*") 而不是 count(col('letter'))

答案 1 :(得分:1)

在计算之前,您需要使用 when 用空值屏蔽非 L 字母:

df\
    .groupby('id')\
    .agg((count(when(col('letter') == 'L', 1)) / count(col('letter'))).alias('prop'))\
    .show()

请注意,count 只会计算非空条目。正如您在代码中所期望的那样,它不仅计算 true 条目。如果您使用 Spark SQL 中的 count_if,您的代码更合适。