#apache-spark #pyspark #apache-spark-sql #aggregation
#apache-spark #pyspark #apache-spark-sql #агрегация
Вопрос:
У меня есть следующий набор данных. Я хочу сгруппировать все переменные и разделить данные на основе приведенных ниже условий.
Тем не менее, я получаю сообщение об ошибке, когда я попробовал приведенный ниже код.
CUST_ID NAME GENDER AGE
id_01 MONEY F 43
id_02 BAKER F 32
id_03 VOICE M 31
id_04 TIME M 56
id_05 TIME F 24
id_06 TALENT F 28
id_07 ISLAND F 21
id_08 ISLAND F 27
id_09 TUME F 24
id_10 TIME F 75
id_11 SKY M 35
id_12 VOICE M 70
from pyspark.sql.functions import *
df.groupBy("CUST_ID", "NAME", "GENDER", "AGE").agg(
CUST_ID.count AS TOTAL
SUM(WHEN ((AGE >= 18 AND AGE <= 34) AND GENDER = 'M') THEN COUNT(CUST_ID) ELSE 0 END AS "M18-34")
SUM(WHEN ((AGE >= 18 AND AGE <= 34) AND GENDER = 'F') THEN COUNT(CUST_ID) ELSE 0 END AS "F18-34")
SUM(WHEN ((AGE >= 18 AND AGE <= 34 THEN COUNT(CUST_ID) ELSE 0 END AS "18-34")
SUM(WHEN ((AGE >= 25 AND AGE <= 54 THEN COUNT(CUST_ID) ELSE 0 END AS "25-54")
SUM(WHEN ((AGE >= 25 AND AGE <= 54) AND GENDER = 'F') THEN COUNT(CUST_ID) ELSE 0 END AS "F25-54")
SUM(WHEN ((AGE >= 25 AND AGE <= 54) AND GENDER = 'M') THEN COUNT(CUST_ID) ELSE 0 END AS "M25-54")
)
Я был бы признателен за вашу помощь / предложения
Заранее спасибо
Ответ №1:
Ваш код не является ни допустимым pyspark, ни допустимым Spark SQL. Существует так много синтаксических проблем. Я попытался исправить их ниже, не уверен, что это то, что вы хотели. Если у вас так много SQL-подобных операторов, лучше использовать Spark SQL напрямую, а не pyspark API:
df.createOrReplaceTempView('df')
result = spark.sql("""
SELECT NAME,
COUNT(CUST_ID) AS TOTAL,
SUM(CASE WHEN ((AGE >= 18 AND AGE <= 34) AND GENDER = 'M') THEN 1 ELSE 0 END) AS `M18-34`,
SUM(CASE WHEN ((AGE >= 18 AND AGE <= 34) AND GENDER = 'F') THEN 1 ELSE 0 END) AS `F18-34`,
SUM(CASE WHEN (AGE >= 18 AND AGE <= 34) THEN 1 ELSE 0 END) AS `18-34`,
SUM(CASE WHEN (AGE >= 25 AND AGE <= 54) THEN 1 ELSE 0 END) AS `25-54`,
SUM(CASE WHEN ((AGE >= 25 AND AGE <= 54) AND GENDER = 'F') THEN 1 ELSE 0 END) AS `F25-54`,
SUM(CASE WHEN ((AGE >= 25 AND AGE <= 54) AND GENDER = 'M') THEN 1 ELSE 0 END) AS `M25-54`
FROM df
GROUP BY NAME
""")
result.show()
------ ----- ------ ------ ----- ----- ------ ------
| NAME|TOTAL|M18-34|F18-34|18-34|25-54|F25-54|M25-54|
------ ----- ------ ------ ----- ----- ------ ------
|ISLAND| 2| 0| 2| 2| 1| 1| 0|
| MONEY| 1| 0| 0| 0| 1| 1| 0|
| TIME| 3| 0| 1| 1| 0| 0| 0|
| VOICE| 2| 1| 0| 1| 1| 0| 1|
| TUME| 1| 0| 1| 1| 0| 0| 0|
| BAKER| 1| 0| 1| 1| 1| 1| 0|
|TALENT| 1| 0| 1| 1| 1| 1| 0|
| SKY| 1| 0| 0| 0| 1| 0| 1|
------ ----- ------ ------ ----- ----- ------ ------
Если вам нужно решение pyspark, вот пример того, как это сделать для первого столбца. Остальное вы можете решить прямолинейно.
import pyspark.sql.functions as F
result = df.groupBy('Name').agg(
F.count('CUST_ID').alias('TOTAL'),
F.count(F.when(F.expr("(AGE >= 18 AND AGE <= 34) AND GENDER = 'M'"), 1)).alias("M18-34")
)
result.show()
------ ----- ------
| Name|TOTAL|M18-34|
------ ----- ------
|ISLAND| 2| 0|
| MONEY| 1| 0|
| TIME| 3| 0|
| VOICE| 2| 1|
| TUME| 1| 0|
| BAKER| 1| 0|
|TALENT| 1| 0|
| SKY| 1| 0|
------ ----- ------
Комментарии:
1. извините, я переводил SQL-запрос в spark. но я также хочу их сгруппировать. итак, у меня должна быть сумма для каждого имени. извините, если слишком много вопросов, как я могу выполнить то же самое в pyspark
2. один короткий вопрос. можно ли группировать на основе нескольких столбцов
3. @JamesTaylor конечно, но в этом примере я думаю, что группировка по имени имеет больше смысла, чем группировка по всем столбцам.
4. @ mck Я пытался брать дроби, но вместо этого не работает общее количество 🙂
5. @ mck Я имею в виду, можем ли мы разделить все столбцы на общее количество, вот чего я пытаюсь достичь