簡體   English   中英

Spark SQL分區依據,窗口,順序依據,計數

[英]Spark SQL Partition By, Window, Order By, Count

假設我有一個包含雜志訂閱信息的數據框:

subscription_id    user_id       created_at       expiration_date
 12384               1           2018-08-10        2018-12-10
 83294               1           2018-06-03        2018-10-03
 98234               1           2018-04-08        2018-08-08
 24903               2           2018-05-08        2018-07-08
 32843               2           2018-03-25        2018-05-25
 09283               2           2018-04-07        2018-06-07

現在,我想添加一列,指出用戶在此當前訂閱開始之前已過期的先前訂閱數量。 換句話說,與給定用戶關聯的到期日期早於該訂閱的開始日期。 這是所需的全部輸出:

subscription_id    user_id       created_at       expiration_date   previous_expired
 12384               1           2018-08-10        2018-12-10          1
 83294               1           2018-06-03        2018-10-03          0
 98234               1           2018-04-08        2018-08-08          0
 24903               2           2018-05-08        2018-07-08          2
 32843               2           2018-03-25        2018-05-03          1
 09283               2           2018-01-25        2018-02-25          0

嘗試:

編輯:使用Python嘗試了各種滯后/超前/等,我現在認為這是一個SQL問題

df = df.withColumn('shiftlag', func.lag(df.expires_at).over(Window.partitionBy('user_id').orderBy('created_at')))

<---編輯,編輯:沒關系,這不起作用

我想我用盡了滯后/超前/移位方法,卻發現它不起作用。 我現在認為最好是使用Spark SQL進行此操作,也許是case when生成新列的case when ,並結合一個having count ,按ID分組的情況?

使用PySpark弄清楚了:

我首先創建了另一列,其中包含每個用戶的所有到期日期的數組:

joined_array = df.groupBy('user_id').agg(collect_set('expiration_date'))

然后將該數組連接回原始數據框:

joined_array = joined_array.toDF('user_idDROP', 'expiration_date_array')
df = df.join(joined_array, df.user_id == joined_array.user_idDROP, how = 'left').drop('user_idDROP')

然后創建一個函數以遍歷數組,如果創建的日期大於到期日期,則在計數中加1:

def check_expiration_count(created_at, expiration_array):
  if not expiration_array:
    return 0
  else:
   count = 0
    for i in expiration_array:
  if created_at > i:
    count += 1
return count

check_expiration_count = udf(check_expiration_count, IntegerType())

然后應用該函數創建一個具有正確計數的新列:

df = df.withColumn('count_of_subs_ending_before_creation', check_expiration_count(df.created_at, df.expiration_array))

瓦剌。 完成。 謝謝大家(沒人幫忙,還是要謝謝)。 希望有人在2022年發現這個有用

暫無
暫無

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

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