繁体   English   中英

分组数据滞后 function

[英]Lag function on grouped data

我有一个 dataframe 如下:

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

df = spark.createDataFrame([
  {"groupId":"A","Day":"2021-01-27", "ts": "2021-01-27 08:30:57.000", "Username": "user1", "Region": "US"},
  {"groupId":"A","Day":"2021-01-27", "ts": "2021-01-27 08:31:57.014", "Username": "user2", "Region": "US"},
  {"groupId":"A","Day":"2021-01-27", "ts": "2021-01-27 08:32:57.914", "Username": "user1", "Region": "MX"},
  {"groupId":"A","Day":"2021-01-27", "ts": "2021-01-27 08:35:57.914", "Username": "user2", "Region": "CA"},
  {"groupId":"A","Day":"2021-01-27", "ts": "2021-01-27 08:33:57.914", "Username": "user1", "Region": "UK"},
  {"groupId":"A","Day":"2021-01-27", "ts": "2021-01-27 08:34:57.914", "Username": "user1", "Region": "GR"},
  {"groupId":"A","Day":"2021-01-27", "ts": "2021-01-27 08:36:57.914", "Username": "user2", "Region": "IR"}])

w = Window.partitionBy().orderBy("groupId","Username").orderBy("Username","ts")
df2 = df.withColumn("prev_region", f.lag(df.Region).over(w))
地区 用户名 组 ID ts
2021-01-27 我们 用户1 一个 2021-01-27 08:30:57.000
2021-01-27 MX 用户1 一个 2021-01-27 08:32:57.914
2021-01-27 英国 用户1 一个 2021-01-27 08:33:57.914
2021-01-27 GR 用户1 一个 2021-01-27 08:34:57.914
2021-01-27 我们 用户2 一个 2021-01-27 08:31:57.014
2021-01-27 加利福尼亚州 用户2 一个 2021-01-27 08:35:57.914
2021-01-27 红外 用户2 一个 2021-01-27 08:36:57.914

而且,我想知道以前的用户区域是什么,所以我使用了滞后 function。

地区 用户名 组 ID ts prev_region
2021-01-27 我们 用户1 一个 2021-01-27 08:30:57.000 null
2021-01-27 MX 用户1 一个 2021-01-27 08:32:57.914 我们
2021-01-27 英国 用户1 一个 2021-01-27 08:33:57.914 MX
2021-01-27 GR 用户1 一个 2021-01-27 08:34:57.914 英国
2021-01-27 我们 用户2 一个 2021-01-27 08:31:57.014 GR
2021-01-27 加利福尼亚州 用户2 一个 2021-01-27 08:35:57.914 我们
2021-01-27 红外 用户2 一个 2021-01-27 08:36:57.914 加利福尼亚州

如您所见,user2 的第一条记录中的“prev region”列的值应为“null”; 但是,这是错误的值。 如果你能告诉我如何解决它,我将不胜感激。

你快到了。

只需根据您的 DataFrame,指定 windows function 即可,如下所示。

# Python API
>>> w = Window.partitionBy("Username").orderBy("groupId", "Username", "ts")
>>> df2.show(truncate=100)
+----------+------+--------+-------+-----------------------+-----------+
|       Day|Region|Username|groupId|                     ts|prev_region|
+----------+------+--------+-------+-----------------------+-----------+
|2021-01-27|    US|   user1|      A|2021-01-27 08:30:57.000|       null|
|2021-01-27|    MX|   user1|      A|2021-01-27 08:32:57.914|         US|
|2021-01-27|    UK|   user1|      A|2021-01-27 08:33:57.914|         MX|
|2021-01-27|    GR|   user1|      A|2021-01-27 08:34:57.914|         UK|
|2021-01-27|    US|   user2|      A|2021-01-27 08:31:57.014|       null|
|2021-01-27|    CA|   user2|      A|2021-01-27 08:35:57.914|         US|
|2021-01-27|    IR|   user2|      A|2021-01-27 08:36:57.914|         CA|
+----------+------+--------+-------+-----------------------+-----------+

# SQL API
df.createOrReplaceTempView("df")
result = spark.sql("""
    SELECT 
        Day, Region, Username, groupId, ts, 
        LAG(Region) OVER (PARTITION BY Username ORDER BY groupId, Username, ts) as rank
    FROM df 
    """)
result.show(truncate=100)
+----------+------+--------+-------+-----------------------+----+
|       Day|Region|Username|groupId|                     ts|rank|
+----------+------+--------+-------+-----------------------+----+
|2021-01-27|    US|   user1|      A|2021-01-27 08:30:57.000|null|
|2021-01-27|    MX|   user1|      A|2021-01-27 08:32:57.914|  US|
|2021-01-27|    UK|   user1|      A|2021-01-27 08:33:57.914|  MX|
|2021-01-27|    GR|   user1|      A|2021-01-27 08:34:57.914|  UK|
|2021-01-27|    US|   user2|      A|2021-01-27 08:31:57.014|null|
|2021-01-27|    CA|   user2|      A|2021-01-27 08:35:57.914|  US|
|2021-01-27|    IR|   user2|      A|2021-01-27 08:36:57.914|  CA|
+----------+------+--------+-------+-----------------------+----+

如果有多个组(多个groupId ),则 state window function 如下:

>>> w = Window.partitionBy("groupId", "Username").orderBy("groupId", "ts", "Username")

您只需在partitionBy function 中添加您的Username名列。 也没有必要有两个订单由orderBy调用。 将您的行更改为:

w = Window.partitionBy('Username').orderBy("ts")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM