Apache spark Pyspark如果存在滚动日期时间记录,如何创建列并填写True/False
数据集包含有每日记录的产品,但有时会遗漏,所以我想创建额外的列来显示它在过去几天中是否存在 我有以下条件 创建T-1、T-2等列,并用以下内容填充 如果记录存在,则用1填充T-1,否则为零 原始表格:Apache spark Pyspark如果存在滚动日期时间记录,如何创建列并填写True/False,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,数据集包含有每日记录的产品,但有时会遗漏,所以我想创建额外的列来显示它在过去几天中是否存在 我有以下条件 创建T-1、T-2等列,并用以下内容填充 如果记录存在,则用1填充T-1,否则为零 原始表格: Item Cat DateTime Value A C1 1-1-2021 10 A C1 2-1-2021 10 A C1 3-1-2021 10 A C1 4-1-2021
Item Cat DateTime Value
A C1 1-1-2021 10
A C1 2-1-2021 10
A C1 3-1-2021 10
A C1 4-1-2021 10
A C1 5-1-2021 10
A C1 6-1-2021 10
B C1 1-1-2021 20
B C1 4-1-2021 20
预期结果:
Item Cat DateTime Value T-1 T-2 T-3 T-4 T-5
A C1 1-1-2021 10 0 0 0 0 0
A C1 2-1-2021 10 1 0 0 0 0 (T-1 is 1 as we have 1-1-2021 record)
A C1 3-1-2021 10 1 1 0 0 0
A C1 4-1-2021 10 1 1 1 0 0
A C1 5-1-2021 10 1 1 1 1 0
A C1 6-1-2021 10 1 1 1 1 1
B C1 1-1-2021 20 0 0 0 0 0
B C1 2-1-2021 0 1 0 0 0 0 (2-1-2021 record need to be created with value zero since we miss this from original data-set, plus T-1 is 1 as we have this record from original data-set)
B C1 3-1-2021 0 0 1 0 0 0
B C1 4-1-2021 20 0 0 1 0 0
B C1 5-1-2021 0 1 0 0 1 0
假设原始表数据存储在原始_数据中,我们可以 创建一个临时视图,以使用名为daily_records的spark sql进行查询 生成可能的日期。这是通过从数据集中识别最小日期和最大日期之间的天数来完成的,然后使用表生成函数explode和spaces生成可能的日期 生成所有可能的项目、日期记录 将这些记录与实际记录连接起来,以获得具有值的完整数据集 使用sparksql查询视图,并使用左连接和CASE语句创建附加列 第一步 原始_data.createOrReplaceTempViewdaily_记录 步骤2-4 每日记录=sparkSession.sql 以日期为界 从每日记录中选择minDateTime作为mindate,maxDateTime作为maxdate , 可能的日期如下 选择 date_addmindate,index.pos作为日期时间 从…起 日期界限 横向视图空间日期DiffMaxDate,mindate,索引 , 独特的_项目,如 从每日记录中选择不同的项目、类别 , 可能的项目日期如下 从唯一的\u项目中选择项目、类别、日期时间内部连接可能的\u日期1=1 , 可能的记录如下 选择 p、 项目,, p、 猫, p、 日期时间, r、 价值观 从…起 可能的项目日期p 左连接 每日记录p.Item=r.Item和p.DateTime=r.DateTime 从可能的_记录中选择* 每日记录。创建或替换临时视图每日记录 每日节目 步骤5-将结果存储在所需结果中 这是可选的,但我选择生成sql来创建此数据帧 周期=5个要检查的周期数 句点_列=,.join[ 案例 当t{0}.Value为空时,则为0 其他1 以'T-{0}结尾` .formati用于范围1中的i,句点+1] 句点_join=.join[ 左连接 datediffto_datet.DateTime、to_datet{0}.DateTime={0}和t.Item=t{0}.Item上的每日记录t{0} .formati用于范围1中的i,句点+1] 句点_sql= 选择 t* {0} 从…起 每日记录 {1} 订购人 项目,日期时间 总体安排 如果lenperiod_columns==0 else,{0}.formatperiod_columns, 句号 所需结果=sparkSession.sqlperiod\u sql 期望的结果显示 实际生成的SQL:
SELECT
t.*,
CASE
WHEN t1.Value IS NULL THEN 0
ELSE 1
END as `T-1`,
CASE
WHEN t2.Value IS NULL THEN 0
ELSE 1
END as `T-2`,
CASE
WHEN t3.Value IS NULL THEN 0
ELSE 1
END as `T-3`,
CASE
WHEN t4.Value IS NULL THEN 0
ELSE 1
END as `T-4`,
CASE
WHEN t5.Value IS NULL THEN 0
ELSE 1
END as `T-5`
FROM
daily_records t
LEFT JOIN
daily_records t1 on datediff(to_date(t.DateTime),to_date(t1.DateTime))=1 and t.Item = t1.Item
LEFT JOIN
daily_records t2 on datediff(to_date(t.DateTime),to_date(t2.DateTime))=2 and t.Item = t2.Item
LEFT JOIN
daily_records t3 on datediff(to_date(t.DateTime),to_date(t3.DateTime))=3 and t.Item = t3.Item
LEFT JOIN
daily_records t4 on datediff(to_date(t.DateTime),to_date(t4.DateTime))=4 and t.Item = t4.Item
LEFT JOIN
daily_records t5 on datediff(to_date(t.DateTime),to_date(t5.DateTime))=5 and t.Item = t5.Item
ORDER BY
Item, DateTime
注意。如果DateTime已格式化为日期字段或格式为yyyy mm dd,则to_date是可选的请参阅我关于如何使用自定义项生成行的其他答案谢谢您的帮助,对于上面的SQL部分,我遇到了错误:引用“t.DateTime”不明确,可能是:t.t,t1.t。;第28行位置45我正在用代码更新答案以生成缺少的行再次感谢您的努力和帮助,我有另一个错误无法解决给定输入列的“项”:[daily_records.day,daily_records.T-12,daily_records.T-10,daily_records.date,daily_records.T-13…来自更新脚本。请提供帮助again@foy我刚刚在笔记本中重新运行了这段代码,它很有效。我还重新组织了答案,以便您更容易复制流程。如果有效,请告诉我