Je me demande comment je peux réaliser ce qui suit dans Spark (Pyspark)
Dataframe initial:
+--+---+
|id|num|
+--+---+
|4 |9.0|
+--+---+
|3 |7.0|
+--+---+
|2 |3.0|
+--+---+
|1 |5.0|
+--+---+
Dataframe résultant:
+--+---+-------+
|id|num|new_Col|
+--+---+-------+
|4 |9.0| 7.0 |
+--+---+-------+
|3 |7.0| 3.0 |
+--+---+-------+
|2 |3.0| 5.0 |
+--+---+-------+
Je parviens généralement à "ajouter" de nouvelles colonnes à un cadre de données en utilisant quelque chose comme: df.withColumn("new_Col", df.num * 10)
Cependant, je n'ai aucune idée de la manière dont je peux réaliser ce "décalage de lignes" pour la nouvelle colonne, de sorte que la nouvelle colonne ait la valeur d'un champ de la ligne précédente (comme dans l'exemple). Je n'ai également rien trouvé dans la documentation de l'API sur la manière d'accéder à une certaine ligne d'un DF par index.
Toute aide serait appréciée.
Vous pouvez utiliser la fonction de fenêtre lag
comme suit
from pyspark.sql.functions import lag, col
from pyspark.sql.window import Window
df = sc.parallelize([(4, 9.0), (3, 7.0), (2, 3.0), (1, 5.0)]).toDF(["id", "num"])
w = Window().partitionBy().orderBy(col("id"))
df.select("*", lag("num").over(w).alias("new_col")).na.drop().show()
## +---+---+-------+
## | id|num|new_col|
## +---+---+-------|
## | 2|3.0| 5.0|
## | 3|7.0| 3.0|
## | 4|9.0| 7.0|
## +---+---+-------+
mais il y a quelques points importants:
Alors que le second problème n’est presque jamais un problème, le premier peut être un facteur décisif. Si tel est le cas, convertissez simplement votre DataFrame
en RDD et calculez lag
manuellement. Voir par exemple:
Autres liens utiles:
val df = sc.parallelize(Seq((4, 9.0), (3, 7.0), (2, 3.0), (1, 5.0))).toDF("id", "num")
df.show
+---+---+
| id|num|
+---+---+
| 4|9.0|
| 3|7.0|
| 2|3.0|
| 1|5.0|
+---+---+
df.withColumn("new_column", lag("num", 1, 0).over(w)).show
+---+---+----------+
| id|num|new_column|
+---+---+----------+
| 1|5.0| 0.0|
| 2|3.0| 5.0|
| 3|7.0| 3.0|
| 4|9.0| 7.0|
+---+---+----------+