apache-spark - 窗口函数上的 pyspark case 语句
问题描述
我有一个数据框,我需要在其中检查以下三列以过滤正确的行。
给定数据框输入:
customer_number acct_registration_ts last_login_ts acct_create_ts
28017150 null null 2018-02-13T00:43:26.747+0000
28017150 null null 2014-09-11T15:58:29.593+0000
28017150 2014-05-14T23:11:40.167+0000 null 2014-05-12T00:00:00.000+0000
预期的数据框输出:
customer_number acct_registration_ts last_login_ts acct_create_ts
28017150 2014-05-14T23:11:40.167+0000 null 2014-05-12T00:00:00.000+0000
过滤条件:
- 如果 acct_registration_ts 不是 NULL,则获取 acct_registration_ts 行的最大值。
- 如果 acct_registration_ts 为 NULL,则检查 last_login_ts,如果 last_login_ts 不为 NULL,则获取 last_login_ts 行的最大值。
- 如果 acct_registration_ts 和 last_login_ts 都为 NULL,则获取 acct_create_ts 行的最大值。
这里我需要按 customer_number 列分组,然后应用上述 3 个过滤逻辑。我尝试使用 pyspark 窗口功能,但没有得到预期的输出。任何帮助将非常感激。
解决方案
您可以在所有三列中使用一个窗口:
from pyspark.sql import functions as F, Window
w = Window.partitionBy('customer_number').orderBy(*[F.desc_nulls_last(c) for c in df.columns[1:]])
df2 = df.withColumn('rn', F.dense_rank().over(w)).filter('rn = 1')
df2.show(truncate=False)
+---------------+----------------------------+-------------+----------------------------+---+
|customer_number|acct_registration_ts |last_login_ts|acct_create_ts |rn |
+---------------+----------------------------+-------------+----------------------------+---+
|28017150 |2014-05-14T23:11:40.167+0000|null |2014-05-12T00:00:00.000+0000|1 |
+---------------+----------------------------+-------------+----------------------------+---+
推荐阅读
- java - 添加对象后Java图形变慢
- python - 如何告诉 for 循环从头开始读取文件?
- python - pd.NamedAgg 覆盖以前的列值
- android - 动态应用名称、包名称和应用徽标
- sql - Oracle SQL - 如何根据客户的开始和结束位置安排我的列表?
- java - 从 java 代码到 jvm 字节代码的转换会被认为是编译还是转译?
- azure-pipelines - 有什么方法要求在排队时设置变量?
- angular - 我们如何在 Angular 中使用自定义 HTML 404 页面
- python - Tiny python 添加跳过空行规则,Antlr4
- prebid.js - 我无法下载 prebid.js 的早期版本