簡體   English   中英

Pyspark高級窗口功能

[英]Pyspark advanced window function

這是我的數據框:

FlightDate=[20,40,51,50,60,15,17,37,36,50]
IssuingDate=[10,15,44,45,55,10,2,30,32,24]
Revenue = [100,50,40,70,60,40,30,100,200,100]
Customer = ['a','a','a','a','a','b','b','b','b','b']
df = spark.createDataFrame(pd.DataFrame([Customer,FlightDate,IssuingDate, Revenue]).T, schema=["Customer",'FlightDate', 'IssuingDate','Revenue'])
df.show()

+--------+----------+-----------+-------+
|Customer|FlightDate|IssuingDate|Revenue|
+--------+----------+-----------+-------+
|       a|        20|         10|    100|
|       a|        40|         15|     50|
|       a|        51|         44|     40|
|       a|        50|         45|     70|
|       a|        60|         55|     60|
|       b|        15|         10|     40|
|       b|        27|          2|     30|
|       b|        37|         30|    100|
|       b|        36|         32|    200|
|       b|        50|         24|    100|
+--------+----------+-----------+-------+

為了方便起見,我使用了數天。

對於每個客戶,我想對研究的FlightDate和研究的FlightDate之間+ 10天之間的所有發行日期的收入進行匯總。

也就是說 :

  • 對於第一行:我將第20天到第30天之間的IssuingDate的所有收入相加...在這里給出0。
  • 對於第二行:我總結了第40天到50天之間IssuingDate的所有收入,即40 + 70 = 110

這是期望的結果:

+--------+----------+-----------+-------+------+
|Customer|FlightDate|IssuingDate|Revenue|Result|
+--------+----------+-----------+-------+------+
|       a|        20|         10|    100|     0|
|       a|        40|         15|     50|   110|
|       a|        51|         44|     40|    60|
|       a|        50|         45|     70|    60|
|       a|        60|         55|     60|     0|
|       b|        15|         10|     40|   100|
|       b|        27|          2|     30|   300|
|       b|        37|         30|    100|     0|
|       b|        36|         32|    200|     0|
|       b|        50|         24|    100|     0|
+--------+----------+-----------+-------+------+

我知道它將涉及一些窗口函數,但是這似乎有些棘手。 謝謝

不需要窗口功能。 它只是一個連接和一個agg:

df.alias("df").join(
    df.alias("df_2"),
    on=F.expr(
        "df.Customer = df_2.Customer "
        "and df_2.issuingdate between df.flightdate and df.flightdate+10"
    ), 
    how='left'
).groupBy(
    *('df.{}'.format(c) 
      for c 
      in df.columns)
).agg(
    F.sum(F.coalesce(
        "df_2.revenue", 
        F.lit(0))
    ).alias("result")
).show()

+--------+----------+-----------+-------+------+                                
|Customer|FlightDate|IssuingDate|Revenue|result|
+--------+----------+-----------+-------+------+
|       a|        20|         10|    100|     0|
|       a|        40|         15|     50|   110|
|       a|        50|         45|     70|    60|
|       a|        51|         44|     40|    60|
|       a|        60|         55|     60|     0|
|       b|        15|         10|     40|   100|
|       b|        27|          2|     30|   300|
|       b|        36|         32|    200|     0|
|       b|        37|         30|    100|     0|
|       b|        50|         24|    100|     0|
+--------+----------+-----------+-------+------+

如果您想保留當前行和未來10天的收入,則可以使用以下代碼。

例如

第一行:flightDate = 20,您需要20到30(含兩個日期)之間的收入,這意味着Total Revenue = 100。

第二行:flightDate = 40,您需要40至50(含兩個日期)之間的收入,這意味着總收入= 50(對於日期40)+ 50(對於日期50)= 120。

第三行:flightDate = 50,您需要的收入在50到60之間(包括日期在內),這意味着總收入= 70(對於日期50)+ 40(對於日期51)+ 60(對於日期60)= 170

from pyspark.sql import *
from pyspark.sql.functions import *
import pandas as pd

FlightDate=[20,40,51,50,60,15,17,37,36,50]
IssuingDate=[10,15,44,45,55,10,2,30,32,24]
Revenue = [100,50,40,70,60,40,30,100,200,100]
Customer = ['a','a','a','a','a','b','b','b','b','b']
df = spark.createDataFrame(pd.DataFrame([Customer,FlightDate,IssuingDate, Revenue]).T, schema=["Customer",'FlightDate', 'IssuingDate','Revenue'])


windowSpec = Window.partitionBy("Customer").orderBy("FlightDate").rangeBetween(0,10)
df.withColumn("Sum", sum("Revenue").over(windowSpec)).sort("Customer").show()

結果如下

+--------+----------+-----------+-------+---+
|Customer|FlightDate|IssuingDate|Revenue|Sum|
+--------+----------+-----------+-------+---+
|       a|        20|         10|    100|100|
|       a|        40|         15|     50|120|
|       a|        50|         45|     70|170|
|       a|        51|         44|     40|100|
|       a|        60|         55|     60| 60|
|       b|        15|         10|     40| 70|
|       b|        17|          2|     30| 30|
|       b|        36|         32|    200|300|
|       b|        37|         30|    100|100|
|       b|        50|         24|    100|100|
+--------+----------+-----------+-------+---+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM