Вычислить пропорцию значений в группах

Я пытаюсь вычислить долю определенного значения, встречающегося в определенном столбце в подгруппах.

Пример фрейма данных

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()

Я пытался положиться на этот ответ, но со следующим кодом

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|
+---+--------+

person Ric S    schedule 08.02.2021    source источник


Ответы (2)


Прежде чем считать, вам нужно замаскировать буквы, отличные от L, нулями, используя when:

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

Обратите внимание, что count будет подсчитывать только ненулевые записи. Он не только считает true записи, как вы ожидали в своем коде. Ваш код больше подходит, если вы используете _5 _ из Spark SQL.

person mck    schedule 08.02.2021

Вы можете использовать sum с when вместо этого для подсчета появления 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')).

person blackbishop    schedule 08.02.2021