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