J'ai passé pas mal de temps à lire certaines questions avec les balises pyspark et spark-dataframe et très souvent, je trouve que les affiches ne fournissent pas suffisamment d'informations pour vraiment comprendre leur question. Je commente généralement en leur demandant de publier un MCVE mais parfois leur faire afficher des exemples de données d'entrée/sortie, c'est comme se tirer des dents. Par exemple: voir les commentaires sur cette question .
Peut-être qu'une partie du problème est que les gens ne savent tout simplement pas comment créer facilement un MCVE pour des cadres de données spark. Je pense qu'il serait utile d'avoir une version spark-dataframe de this pandas question comme guide qui peut être lié.
Alors, comment peut-on créer un bon exemple reproductible?
À tout le moins, les affiches devraient fournir quelques lignes et colonnes sur leur trame de données et leur code qui peuvent être utilisées pour les créer facilement. Par simple, je veux dire couper-coller. Faites-le aussi petit que possible pour démontrer votre problème.
J'ai la trame de données suivante:
+-----+---+-----+----------+
|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|
+-----+---+-----+----------+
qui peut être créé avec ce code:
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')
)
Posez votre question spécifique et montrez-nous la sortie souhaitée.
Comment puis-je créer une nouvelle colonne'is_divisible'
qui a de la valeur'yes'
si le jour du mois du'date'
plus 7 jours est divisible par la valeur dans la colonne'X'
, et'no'
sinon?
Sortie souhaitée:
+-----+---+-----+----------+------------+
|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|
+-----+---+-----+----------+------------+
Expliquez en détail comment vous obtenez la sortie souhaitée. Cela aide à montrer un exemple de calcul.
Par exemple dans la ligne 1, le X = 1 et la date = 2017-01-01. L'ajout de 7 jours à ce jour donne le 01-01-2017. Le jour du mois est 8 et comme 8 est divisible par 1, la réponse est 'oui'.
De même, pour la dernière ligne X = 7 et la date = 2017-01-04. L'ajout de 7 à la date donne 11 comme jour du mois. Puisque 11% 7 n'est pas 0, la réponse est "non".
Montrez-nous ce que vous avez fait ou essayé, y compris tout * du code même si cela ne fonctionne pas. Dites-nous où vous êtes bloqué et si vous recevez une erreur, veuillez inclure le message d'erreur.
(* Vous pouvez omettre le code pour créer le contexte spark, mais vous devez inclure toutes les importations.)
Je sais comment ajouter une nouvelle colonne qui estdate
plus 7 jours mais j'ai du mal à obtenir le jour du mois sous forme d'entier.
from pyspark.sql import functions as f
df.withColumn("next_week", f.date_add("date", 7))
Si la question est liée au réglage des performances, veuillez inclure les informations suivantes.
Il est préférable d'inclure plan d'exécution étend. En Python:
df.explain(True)
À Scala:
df.explain(true)
ou plan d'exécution étendu avec statistiques. En Python:
print(df._jdf.queryExecution().stringWithStats())
à Scala:
df.queryExecution.stringWithStats
mode
- local
, client
, `cluster. lent est relatif, en particulier lorsque vous portez une application non distribuée ou que vous vous attendez à une faible latence. Les horaires exacts pour différentes tâches et étapes peuvent être récupérés à partir de Spark UI (sc.uiWebUrl
) jobs
ou Spark REST UI.
L'utilisation de noms établis pour chaque contexte nous permet de reproduire rapidement le problème.
sc
- pour SparkContext
.sqlContext
- pour SQLContext
.spark
- pour SparkSession
.L'inférence de type puissante est l'une des fonctionnalités les plus utiles de Scala, mais il est difficile d'analyser le code hors contexte. Même si le type est évident dans le contexte, il est préférable d'annoter les variables. Préférer
val lines: RDD[String] = sc.textFile("path")
val words: RDD[String] = lines.flatMap(_.split(" "))
plus de
val lines = sc.textFile("path")
val words = lines.flatMap(_.split(" "))
Les outils couramment utilisés peuvent vous aider:
spark-Shell
/Scala Shell
utilisation :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
Utilisation Alt + =
Bonne question et réponse; quelques suggestions supplémentaires:
Spark évolue toujours, mais pas aussi rapidement qu'au temps de 1.x. C'est toujours (mais surtout si vous utilisez une version un peu plus ancienne) une bonne idée d'inclure votre version de travail. Personnellement, je commence toujours mes réponses par:
spark.version
# u'2.2.0'
ou
sc.version
# u'2.2.0'
Inclure votre Python, aussi, n'est jamais une mauvaise idée.
Si votre question ne concerne pas strictement Spark SQL & dataframes, par exemple si vous avez l'intention d'utiliser votre dataframe dans une opération d'apprentissage automatique, soyez explicite sur vos importations - voir cette question =, où les importations n'ont été ajoutées au PO qu'après un échange approfondi dans les commentaires (désormais supprimés) (et il s'est avéré que ces mauvaises importations étaient à l'origine du problème).
Pourquoi est-ce nécessaire? Parce que, par exemple, cette LDA
from pyspark.mllib.clustering import LDA
est différent de ce LDA:
from pyspark.ml.clustering import LDA
le premier provenant de l'ancienne API basée sur RDD (anciennement Spark MLlib)), tandis que le second de la nouvelle API basée sur des trames de données (Spark ML).
OK, j'avoue que c'est subjectif: je crois que les questions PySpark ne devraient pas être marquées comme python
par défaut ; le fait est que la balise python
donne automatiquement la surbrillance du code (et je crois que c'est une raison principale pour ceux qui l'utilisent pour les questions PySpark). Quoi qu'il en soit, si vous êtes d'accord et que vous souhaitez toujours un code Nice surligné, incluez simplement la directive de démarquage appropriée:
<!-- language-all: lang-python -->
quelque part dans votre message, avant votre premier extrait de code.
[MISE À JOUR: J'ai demandé mise en évidence automatique de la syntaxe pour les balises pyspark
et sparkr
- les votes positifs sont les bienvenus]
Cette petite fonction d'aide pourrait aider à analyser Spark fichiers de sortie dans DataFrame:
PySpark:
from pyspark.sql.functions import *
def read_spark_output(file_path):
step1 = spark.read \
.option("header","true") \
.option("inferSchema","true") \
.option("delimiter","|") \
.option("parserLib","UNIVOCITY") \
.option("ignoreLeadingWhiteSpace","true") \
.option("ignoreTrailingWhiteSpace","true") \
.option("comment","+") \
.csv("file://{}".format(file_path))
# select not-null columns
step2 = t.select([c for c in t.columns if not c.startswith("_")])
# deal with 'null' string in column
return step2.select(*[when(~col(col_name).eqNullSafe("null"), col(col_name)).alias(col_name) for col_name in step2.columns])
Scala:
// read Spark Output Fixed width table:
def readSparkOutput(filePath: String): org.Apache.spark.sql.DataFrame = {
val step1 = spark.read
.option("header", "true")
.option("inferSchema", "true")
.option("delimiter", "|")
.option("parserLib", "UNIVOCITY")
.option("ignoreLeadingWhiteSpace", "true")
.option("ignoreTrailingWhiteSpace", "true")
.option("comment", "+")
.csv(filePath)
val step2 = step1.select(step1.columns.filterNot(_.startsWith("_c")).map(step1(_)): _*)
val columns = step2.columns
columns.foldLeft(step2)((acc, c) => acc.withColumn(c, when(col(c) =!= "null", col(c))))
}
Usage:
df = read_spark_output("file:///tmp/spark.out")
PS: Pour pyspark, eqNullSafe
est disponible auprès de spark 2.3
.