[英]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.