Cómo hacer buenos ejemplos de marcos de datos Apache Spark reproducibles
He estado pasando una buena cantidad de tiempo leyendo algunas preguntas con las etiquetas pyspark y spark-dataframe y muy a menudo encuentro que los carteles no proporcionan suficiente información para entender realmente su pregunta. Normalmente comento pidiéndoles que publiquen un MCVE pero a veces conseguir que muestren algunos datos de entrada/salida de muestra es como tirar de los dientes. Por ejemplo: ver los comentarios sobre esta pregunta.
Quizás parte del problema es que la gente simplemente no sabe cómo crear fácilmente un MCVE para marcos de datos spark. Creo que sería útil tener una versión spark-dataframe de esta pregunta de pandas como una guía que se pueda vincular.
Entonces, ¿cómo se crea un buen ejemplo reproducible?
4 answers
Proporcione pequeños datos de muestra, que se pueden recrear fácilmente.
Como mínimo, los posters deben proporcionar un par de filas y columnas en su dataframe y código que se puedan usar para crearlo fácilmente. Por fácil, me refiero a cortar y pegar. Hágalo lo más pequeño posible para demostrar su problema.
tengo el siguiente dataframe:
+-----+---+-----+----------+
|index| X|label| date|
+-----+---+-----+----------+
| 1| 1| A|2017-01-01|
| 2| 3| B|2017-01-02|
| 3| 5| A|2017-01-03|
| 4| 7| B|2017-01-04|
+-----+---+-----+----------+
que se puede crear con este código:
df = sqlCtx.createDataFrame(
[
(1, 1, 'A', '2017-01-01'),
(2, 3, 'B', '2017-01-02'),
(3, 5, 'A', '2017-01-03'),
(4, 7, 'B', '2017-01-04')
],
('index', 'X', 'label', 'date')
)
Mostrar el salida.
Haga su pregunta específica y muéstrenos su salida deseada.
¿Cómo puedo crear una nueva columna 'is_divisible'
que tiene el valor 'yes'
si el día de mes de la 'date'
además de los 7 días es divisible por el valor en la columna'X'
, y 'no'
de otra manera?
salida Deseada:
+-----+---+-----+----------+------------+
|index| X|label| date|is_divisible|
+-----+---+-----+----------+------------+
| 1| 1| A|2017-01-01| yes|
| 2| 3| B|2017-01-02| yes|
| 3| 5| A|2017-01-03| yes|
| 4| 7| B|2017-01-04| no|
+-----+---+-----+----------+------------+
Explica cómo obtener tu salida.
Explicar, con gran detalle, cómo se obtiene su salida deseada. Ayuda a mostrar un ejemplo de cálculo.
Por ejemplo, en la fila 1, la X = 1 y la fecha = 2017-01-01. Agregar 7 días hasta la fecha rinde 2017-01-08. El día del mes es 8 y como 8 es divisible por 1, la respuesta es 'sí'.
Del mismo modo, para la última fila X = 7 y la fecha = 2017-01-04. Agregar 7 a la fecha produce 11 como el día del mes. Dado que 11% 7 no es 0, la respuesta es "no".
Compartir su existente codificar.
Muéstranos lo que has hecho o intentado, incluyendo todo* del código incluso si no funciona. Díganos dónde se está quedando atascado y si recibe un error, incluya el mensaje de error.
(*Puede omitir el código para crear el contexto spark, pero debe incluir todas las importaciones.)
Sé cómo agregar una nueva columna que es date
más 7 días, pero estoy teniendo problemas para conseguir el día del mes como un entero.
from pyspark.sql import functions as f
df.withColumn("next_week", f.date_add("date", 7))
Incluye versiones, importaciones y usa resaltado de sintaxis
- Detalles completos en esta respuesta escrita por desertnaut .
Para los puestos de ajuste de rendimiento, incluya el plan de ejecución
- Detalles completos en esta respuesta escrita por user8371915.
- Ayuda el uso de nombres estandarizados para contextos.
Análisis de la salida de chispa files
- MaxU proporcionó un código útil en esta respuesta para ayudar a analizar los archivos de salida de Spark en un DataFrame.
Otras notas.
- Asegúrese de leer cómo preguntary Cómo crear un ejemplo Mínimo, Completo y Verificable primero.
- Lea las otras respuestas a esta pregunta, que están enlazadas arriba.
- Tenga un buen título descriptivo. Sé cortés. La gente en SO are voluntarios, así que pedid amablemente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-02 03:23:14
Ajuste de rendimiento
Si la pregunta está relacionada con el ajuste de rendimiento, incluya la siguiente información.
Plan de ejecución
Es mejor incluir plan de ejecución extendido. En Python:
df.explain(True)
En Scala:
df.explain(true)
O plan de ejecución ampliado con estadísticas. En Python:
print(df._jdf.queryExecution().stringWithStats())
En Scala:
df.queryExecution.stringWithStats
Modo e información del clúster
-
mode
-local
,client
, `Cluster. - Administrador de clústeres (si corresponde) - ninguno (modo local), independiente, YARN, Mesos, Kubernetes.
- Información básica de configuración (número de núcleos, memoria del ejecutor).
Información de tiempo
slow es relativo, especialmente cuando portas una aplicación no distribuida o esperas una latencia baja. Los tiempos exactos para diferentes tareas y etapas se pueden recuperar desde la interfaz de usuario de Spark (sc.uiWebUrl
) jobs
o Spark REST UI.
Usar nombres estandarizados para contextos
El uso de nombres establecidos para cada contexto nos permite reproducir rápidamente el problema.
-
sc
paraSparkContext
. -
sqlContext
paraSQLContext
. -
spark
paraSparkSession
.
Proporcionar información de tipo (Scala )
La poderosa inferencia de tipos es una de las características más útiles de Scala, pero hace difícil analizar código sacado de contexto. Incluso si el tipo es obvio desde el contexto, es mejor anotar el variable. Prefer
val lines: RDD[String] = sc.textFile("path")
val words: RDD[String] = lines.flatMap(_.split(" "))
Sobre
val lines = sc.textFile("path")
val words = lines.flatMap(_.split(" "))
Las herramientas de uso común pueden ayudarlo:
-
spark-shell
/ Scala shellUse
:t
scala> val rdd = sc.textFile("README.md") rdd: org.apache.spark.rdd.RDD[String] = README.md MapPartitionsRDD[1] at textFile at <console>:24 scala> :t rdd org.apache.spark.rdd.RDD[String]
-
InteliJ Idea
Use Alt + =
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-27 10:41:28
Buena pregunta y respuesta; algunas sugerencias adicionales:
Incluye tu versión de Spark
La chispa todavía está evolucionando, aunque no tan rápidamente como en los días de 1.x. Siempre es (pero especialmente si está utilizando una versión algo más antigua) una buena idea incluir su versión de trabajo. Personalmente, siempre comienzo mis respuestas con:
spark.version
# u'2.2.0'
O
sc.version
# u'2.2.0'
Incluir tu versión de Python, también, nunca es una mala idea.
Incluya todos sus importaciones
Si su pregunta no es estrictamente sobre Spark SQL & dataframes, por ejemplo, si tiene la intención de usar su dataframe en alguna operación de aprendizaje automático, sea explícito sobre sus importaciones - vea esta pregunta, donde las importaciones se agregaron en el OP solo después de un extenso intercambio en los comentarios (ahora eliminados) (y resultó que estas importaciones incorrectas fueron la causa raíz del problema).
¿Por qué es necesario esto? Porque, por ejemplo, este LDA
from pyspark.mllib.clustering import LDA
Es diferente de este LDA:
from pyspark.ml.clustering import LDA
La primera proviene de la antigua API basada en RDD (anteriormente Spark MLlib), mientras que la segunda proviene de la nueva API basada en dataframe (Spark ML).
Incluir resaltado de código
Bien, confieso que esto es subjetivo: creo que las preguntas de PySpark no deben etiquetarse como python
por defecto ; la cosa es, python
etiqueta da automáticamente el código de resaltado (y creo que esta es una razón principal para aquellos que lo utilizan para PySpark preguntas). De todos modos, si estás de acuerdo, y todavía te gustaría un código bien resaltado, simplemente incluye la directiva markdown relevante:
<!-- language-all: lang-python -->
En algún lugar de tu post, antes de tu primer fragmento de código.
[ACTUALIZACIÓN: He solicitado resaltado de sintaxis automático para pyspark
y sparkr
etiquetas-votos positivos más bienvenidos]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-29 00:58:25
Esta pequeña función auxiliar podría ayudar a analizar los archivos de salida de Spark en DataFrame:
PySpark:
def read_spark_output(file_path):
t = spark.read \
.option("header","true") \
.option("inferSchema","true") \
.option("delimiter","|") \
.option("parserLib","UNIVOCITY") \
.option("ignoreLeadingWhiteSpace","true") \
.option("ignoreTrailingWhiteSpace","true") \
.option("comment","+") \
.csv("file:///tmp/spark.out")
# select not-null columns
return t.select([c for c in t.columns if not c.startswith("_")])
Scala:
// read Spark Output Fixed width table:
def readSparkOutput(filePath: String) : org.apache.spark.sql.DataFrame = {
val t = spark.read
.option("header","true")
.option("inferSchema","true")
.option("delimiter","|")
.option("parserLib","UNIVOCITY")
.option("ignoreLeadingWhiteSpace","true")
.option("ignoreTrailingWhiteSpace","true")
.option("comment","+")
.csv(filePath)
t.select(t.columns.filterNot(_.startsWith("_c")).map(t(_)):_*)
}
Uso:
df = read_spark_output("file:///tmp/spark.out")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-26 00:15:47