SQL/Pyspark查询以组合同一组的聚合中的每个值

发布于 2025-01-29 17:11:21 字数 3216 浏览 3 评论 0 原文

假设我有一个类似此

ID 日期
1 01/04 7
1 01/03 2
1 01/02 10
1 01/01 4
2 01/01/04 7
2 01/01/03 7
2 01/02 8
2 01/01 5

我要获得的是另一个表,该表具有相同数量的记录,每个记录都有一个额外的列,其中最后一个 n 记录的平均值具有相同的 id 这只是在给定记录之前的日期。例如,如果 n = 2 对于第二行,则使用 id = 1 date = 01/03 我想拥有在具有相同 ID 的两个行中 value 的平均值,并且只是 01/03 之前的两个日期(10+4)/2 = 7。因此,对于此特定记录,我将拥有:

ID 日期 AVG最后2个记录相同组
1 01/04 7 6
1 01/01/03 2 7
1 01/02 10 4
1 01/01 4 NENULL
2 01/04 7 7.5 7.5 7.5 7.5
2 01/03 7 6.5
2 01/02 8 5
2 01/01 5 我的问题

是如何以关系(SQL)逻辑实现此问题(Pyspark中的实现也有很大帮助)。

提前致谢

Suppose I have a table like this

id date value
1 01/04 7
1 01/03 2
1 01/02 10
1 01/01 4
2 01/04 7
2 01/03 7
2 01/02 8
2 01/01 5

What I want to get is another table which the same number of records and that for each record has an extra column with the average value of the last n records with the same id that hast just dates before the given record. For example, if n=2, for the second row, with id=1 and date=01/03 I would like to have the value of the average of value in the two rows that have the same idand are just the two dates just before 01/03, that is (10+4)/2=7. So, for this specific record, I would have:

id date value avg last 2 records same group
1 01/04 7 6
1 01/03 2 7
1 01/02 10 4
1 01/01 4 null
2 01/04 7 7.5
2 01/03 7 6.5
2 01/02 8 5
2 01/01 5 null

My question is how to implement this in relational (SQL) logic (also implementations in Pyspark would help a lot).

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

新雨望断虹 2025-02-05 17:11:21

您可以使用,通过 ID 进行分区,并通过 date 进行排序。

设置

from pyspark.sql import functions as F
from pyspark.sql import Window

df = spark.createDataFrame(
    [(1, '01/04', 7),
    (1, '01/03', 2),
    (1, '01/02', 10),
    (1, '01/01', 4),
    (2, '01/04', 7),
    (2, '01/03', 7),
    (2, '01/02', 8),
    (2, '01/01', 5)],
    ['id', 'date', 'value']
)
df.createOrReplaceTempView('sample_data')

Pyspark(DataFrame API)

w = Window().partitionBy('id').orderBy('date').rowsBetween(-2, -1)

df = df.withColumn('avg', F.avg('value').over(w))

df.orderBy(F.col('id').asc(), F.col('date').desc()).show()

+---+-----+-----+----+
| id| date|value| avg|
+---+-----+-----+----+
|  1|01/04|    7| 6.0|
|  1|01/03|    2| 7.0|
|  1|01/02|   10| 4.0|
|  1|01/01|    4|null|
|  2|01/04|    7| 7.5|
|  2|01/03|    7| 6.5|
|  2|01/02|    8| 5.0|
|  2|01/01|    5|null|
+---+-----+-----+----+

SQL

spark.sql(
    '''
    SELECT
    id,
    date,
    value,
    AVG(value) OVER (PARTITION BY id ORDER BY date ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS avg
    FROM sample_data
    ORDER BY id, date DESC
    ''').show()

+---+-----+-----+----+
| id| date|value| avg|
+---+-----+-----+----+
|  1|01/04|    7| 6.0|
|  1|01/03|    2| 7.0|
|  1|01/02|   10| 4.0|
|  1|01/01|    4|null|
|  2|01/04|    7| 7.5|
|  2|01/03|    7| 6.5|
|  2|01/02|    8| 5.0|
|  2|01/01|    5|null|
+---+-----+-----+----+

You can do so with a window function, partitioning by id and sorting by date.

Setup

from pyspark.sql import functions as F
from pyspark.sql import Window

df = spark.createDataFrame(
    [(1, '01/04', 7),
    (1, '01/03', 2),
    (1, '01/02', 10),
    (1, '01/01', 4),
    (2, '01/04', 7),
    (2, '01/03', 7),
    (2, '01/02', 8),
    (2, '01/01', 5)],
    ['id', 'date', 'value']
)
df.createOrReplaceTempView('sample_data')

PySpark (dataframe API)

w = Window().partitionBy('id').orderBy('date').rowsBetween(-2, -1)

df = df.withColumn('avg', F.avg('value').over(w))

df.orderBy(F.col('id').asc(), F.col('date').desc()).show()

+---+-----+-----+----+
| id| date|value| avg|
+---+-----+-----+----+
|  1|01/04|    7| 6.0|
|  1|01/03|    2| 7.0|
|  1|01/02|   10| 4.0|
|  1|01/01|    4|null|
|  2|01/04|    7| 7.5|
|  2|01/03|    7| 6.5|
|  2|01/02|    8| 5.0|
|  2|01/01|    5|null|
+---+-----+-----+----+

SQL

spark.sql(
    '''
    SELECT
    id,
    date,
    value,
    AVG(value) OVER (PARTITION BY id ORDER BY date ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS avg
    FROM sample_data
    ORDER BY id, date DESC
    ''').show()

+---+-----+-----+----+
| id| date|value| avg|
+---+-----+-----+----+
|  1|01/04|    7| 6.0|
|  1|01/03|    2| 7.0|
|  1|01/02|   10| 4.0|
|  1|01/01|    4|null|
|  2|01/04|    7| 7.5|
|  2|01/03|    7| 6.5|
|  2|01/02|    8| 5.0|
|  2|01/01|    5|null|
+---+-----+-----+----+
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文