SQL Query to Py(spark)
Tengo la siguiente consulta SQL que quiero convertir a pyspark. Quiero tomar dos columnas pp y género y hacer lo siguiente en pyspark
%sql
SELECT pp
, SUM(CASE WHEN Gender = 'M'
THEN 1.0 ELSE 0.0 END) /
COUNT(1) AS gender_score
, count(1) AS total
FROM df
WHERE gender in ('M', 'F')
GROUP BY pp
HAVING count(1) > 100
Lo intenté.
from pyspark.sql.functions import expr
test_df = df.withColumn("gender_score", expr("CASE WHEN Gender == 'M' THEN 1 WHEN Gender == 'F' THEN 0 ELSE 'other' END AS male_score"))
Pero no sé cómo puedo seleccionar sólo 2 columnas en pyspark y reproducir la consulta SQL antes mencionada para pyspark
Gracias por adelantado
Pregunta hecha hace 3 años, 4 meses, 29 días - Por geekglitcher1735
4 Respuestas:
-
Si quieres una solución de pitón:
import pyspark.sql.functions as F def df_func(df, grp): test_df = df.filter( F.col('gender').isin(['M','F']) ).groupBy(grp).agg( F.mean( F.when(F.col('Gender') == F.lit('M'), 1.0).otherwise(0.0) ).alias('gender_score'), F.count(F.lit(1)).alias('total') ).filter('total > 100') return test_df result = df_func(df, 'pp')
Puede utilizar Spark SQL creando una vista temporal de su dataframe:
df.createOrReplaceTempView('df') query = """ SELECT pp , SUM(CASE WHEN Gender = 'M' THEN 1.0 ELSE 0.0 END) / COUNT(1) AS gender_score , count(1) AS total FROM df WHERE gender in ('M', 'F') GROUP BY pp HAVING count(1) > 100 """ test_df = spark.sql(query)
Respondida el Dec 16, 2020 a las 10:29 - por algorithmadept
Votos positivos: 0 | Votos negativos: 0 -
El grupoPor funciones agg() toma múltiples expresiones. Así que puedes hacer una expresión suma/conta.
val df = spark.sql(""" with t1( select 10 pp, 'M' gender union all select 10 pp, 'F' gender union all select 10 pp, 'M' gender union all select 40 pp, 'F' gender ) select * from t1 """) df.show(false) +---+------+ |pp |gender| +---+------+ |10 |M | |10 |F | |10 |M | |40 |F | +---+------+ df.groupBy("pp").agg ( (sum(expr("CASE WHEN Gender = 'M' THEN 1 ELSE 0 END "))/count(lit(1)) ).alias("gender_score"), count(lit(1)).alias("total") ).show(false) +---+------------------+-----+ |pp |gender_score |total| +---+------------------+-----+ |40 |0.0 |1 | |10 |0.6666666666666666|3 | +---+------------------+-----+
Después de eso puede implementar "tener" usando otro filtro.
Respondida el Dec 16, 2020 a las 10:38 - por techtactician
Votos positivos: 0 | Votos negativos: 0 -
Para lograr lo que deseas en pyspark, primero necesitas seleccionar las dos columnas
pp
ygender
, luego realizar los cálculos necesarios y finalmente aplicar las condiciones de filtrado y agrupamiento. Aquí te muestro cómo puedes hacerlo:python from pyspark.sql import SparkSession from pyspark.sql.functions import expr
Crear la sesión de Spark
spark = SparkSession.builder.appName("example").getOrCreate()Cargar el DataFrame
df = spark.read.load("path_to_your_data_file")Seleccionar las columnas 'pp' y 'gender'
df_select = df.select("pp", "gender")Realizar los cálculos y filtros
results = df_select.filter("gender in ('M', 'F')") \ .groupBy("pp") \ .agg((sum(expr("CASE WHEN gender = 'M' THEN 1.0 ELSE 0.0 END")) / count("")).alias("gender_score"), count("").alias("total")) \ .filter("total > 100")Mostrar los resultados
results.show()En este código, primero se seleccionan las columnas
pp
ygender
. Luego, se aplican los cálculos conagg
para obtenergender_score
ytotal
de acuerdo a la lógica de la consulta SQL original. Finalmente, se filtran los resultados con la condicióntotal > 100
y se muestran los resultados.Asegúrate de ajustar el nombre del archivo de datos en la línea
df = spark.read.load("path_to_your_data_file")
con la ruta correcta de tus datos.Respondida el Dec 17, 2020 a las 10:29 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
python from pyspark.sql import functions as F
Select only the 'pp' and 'Gender' columns
selected_df = df.select('pp', 'Gender')Calculate the gender score and total count
gender_score = selected_df.groupBy('pp').agg( F.sum(F.when(F.col('Gender') == 'M', 1.0).otherwise(0.0)) / F.count(F.col('Gender')), F.count(F.col('Gender')).alias('total') )Filter the results to only include rows with a total count greater than 100
filtered_df = gender_score.filter(F.col('total') > 100)Select only the 'pp' and 'gender_score' columns from the filtered results
result_df = filtered_df.select('pp', 'gender_score')Respondida el Dec 17, 2020 a las 10:39 - por Gemini
Votos positivos: 0 | Votos negativos: 0