如何从PySpark DataFrame提取日期生成唯一值时间维度表
解决方案:从多列日期生成PySpark时间维度表
我来帮你搞定这个需求!要从包含多列日期的PySpark DataFrame中提取所有唯一日期,生成结构为date|day|month|year|dayofweek的时间维度表,咱们可以分三步来实现:
步骤1:将多列日期转置为单列并去重
首先需要把分散在不同列的日期全部归集到同一列,然后去掉重复的日期值。这里可以用stack函数来实现列的转置(unpivot):
from pyspark.sql import functions as F from pyspark.sql.types import DateType # 替换成你的原始DataFrame名称 df = your_original_dataframe # 方法1:手动指定日期列名 date_columns = ["order_date", "ship_date", "deliver_date"] # 示例日期列,替换为实际列名 # 方法2:自动识别所有日期类型的列(更灵活) date_columns = [col.name for col in df.schema.fields if isinstance(col.dataType, DateType)] # 使用stack函数转置多列为单列,同时保留原列名(可选,后续可以丢弃) unpivoted_df = df.selectExpr( f"stack({len(date_columns)}, {', '.join([f'{col}, \'{col}\'' for col in date_columns])}) as (date_value, source_column)" ).select("date_value") # 去重,保留唯一日期 unique_dates_df = unpivoted_df.dropDuplicates(["date_value"])
步骤2:提取日期维度字段
接下来用PySpark内置的日期函数,从唯一日期中提取day、month、year和dayofweek:
dim_date_df = unique_dates_df.withColumn("day", F.dayofmonth("date_value")) \ .withColumn("month", F.month("date_value")) \ .withColumn("year", F.year("date_value")) \ .withColumn("dayofweek", F.dayofweek("date_value")) \ .withColumnRenamed("date_value", "date") \ .select("date", "day", "month", "year", "dayofweek")
关于dayofweek的小细节
PySpark的dayofweek函数默认返回值:1代表周日,2代表周一,……,7代表周六。如果你的业务逻辑需要周一为一周的第一天,可以调整计算方式:
# 调整dayofweek,让周一=1,周日=7 dim_date_df = dim_date_df.withColumn( "dayofweek", (F.dayofweek("date") + 5) % 7 + 1 )
步骤3:验证结果
最后可以查看生成的时间维度表:
dim_date_df.show(5)
输出示例(调整后dayofweek的结果):
+----------+---+-----+----+---------+ | date|day|month|year|dayofweek| +----------+---+-----+----+---------+ |2023-01-01| 1| 1|2023| 7| |2023-01-02| 2| 1|2023| 1| |2023-01-03| 3| 1|2023| 2| +----------+---+-----+----+---------+
内容的提问来源于stack exchange,提问作者tmoe
相关产品推荐
相关产品推荐

