web-dev-qa-db-fra.com

Application d'une fonction Window pour calculer les différences dans pySpark

J'utilise pySpark et j'ai configuré mon dataframe avec deux colonnes représentant un prix d'actif quotidien comme suit:

ind = sc.parallelize(range(1,5))
prices = sc.parallelize([33.3,31.1,51.2,21.3])
data = ind.Zip(prices)
df = sqlCtx.createDataFrame(data,["day","price"])

J'obtiens en appliquant df.show():

+---+-----+
|day|price|
+---+-----+
|  1| 33.3|
|  2| 31.1|
|  3| 51.2|
|  4| 21.3|
+---+-----+

Ce qui est bien et tout. Je voudrais avoir une autre colonne qui contient les rendements quotidiens de la colonne des prix, c'est-à-dire quelque chose comme

(price(day2)-price(day1))/(price(day1))

Après de nombreuses recherches, on me dit que cela est plus efficacement accompli en appliquant les fonctions pyspark.sql.window, Mais je ne peux pas voir comment.

17
Thomas Moore

Vous pouvez apporter la colonne du jour précédent en utilisant la fonction lag , et ajouter une colonne supplémentaire qui effectue le retour quotidien réel des deux colonnes, mais vous devrez peut-être indiquer spark comment partitionner vos données et/ou leur ordonner de faire du lag, quelque chose comme ceci:

from pyspark.sql.window import Window
import pyspark.sql.functions as func
from pyspark.sql.functions import lit

dfu = df.withColumn('user', lit('tmoore'))

df_lag = dfu.withColumn('prev_day_price',
                        func.lag(dfu['price'])
                                 .over(Window.partitionBy("user")))

result = df_lag.withColumn('daily_return', 
          (df_lag['price'] - df_lag['prev_day_price']) / df_lag['price'] )

>>> result.show()
+---+-----+-------+--------------+--------------------+
|day|price|   user|prev_day_price|        daily_return|
+---+-----+-------+--------------+--------------------+
|  1| 33.3| tmoore|          null|                null|
|  2| 31.1| tmoore|          33.3|-0.07073954983922816|
|  3| 51.2| tmoore|          31.1|         0.392578125|
|  4| 21.3| tmoore|          51.2|  -1.403755868544601|
+---+-----+-------+--------------+--------------------+

Voici une introduction plus longue à Fonctions de fenêtre dans Spark .

33
Oleksiy

Lag La fonction peut vous aider à résoudre votre cas d'utilisation.

from pyspark.sql.window import Window
import pyspark.sql.functions as func

### Defining the window 
Windowspec=Window.orderBy("day")

### Calculating lag of price at each day level
prev_day_price= df.withColumn('prev_day_price',
                        func.lag(dfu['price'])
                                .over(Windowspec))

### Calculating the average                                  
result = prev_day_price.withColumn('daily_return', 
          (prev_day_price['price'] - prev_day_price['prev_day_price']) / 
prev_day_price['price'] )
2
Sushmita Konar