Spark Scala如何将DataFrame小时字符串列按区间映射为对应时段
你可以把字符串格式的时间统一转换为可直接比较的数值/时间类型,绕开时间跨天排序的问题。这里提供两种可行实现方案:
方案1:转换为当日总分钟数做数值比较
把时间拆解为小时、分钟后换算为从0点开始的总分钟数,所有时间都映射为0~1439的整数,直接做数值比较即可:
# 导入需要的函数 from pyspark.sql.functions import col, split, when, lit df = df.withColumn("total_min", # 按冒号拆分时间,分别取小时、分钟转整数后计算总分钟 split(col("DepTime"), ":").getItem(0).cast("int") * 60 + split(col("DepTime"), ":").getItem(1).cast("int") ) \ .withColumn("DepTime", # 06:00=360分钟 11:59=719分钟 when((col("total_min") >= 360) & (col("total_min") <= 719), lit("Morning")) # 12:00=720分钟 17:00=1020分钟 .when((col("total_min") >= 720) & (col("total_min") <= 1020), lit("Afternoon")) # 17:01=1021分钟 20:00=1200分钟 .when((col("total_min") >= 1021) & (col("total_min") <= 1200), lit("Evening")) # 剩余区间自动归为Night(含20:01~23:59、00:00~05:59) .otherwise(lit("Night")) ) \ # 删除中间计算的辅助列 .drop("total_min")
方案2:转换为时间类型直接比较
如果想要更直观的代码可读性,可以直接把字符串转为时间类型后做区间比较:
from pyspark.sql.functions import col, to_timestamp, when, lit df = df.withColumn("DepTime", when((to_timestamp(col("DepTime"), "HH:mm") >= to_timestamp(lit("06:00"), "HH:mm")) & (to_timestamp(col("DepTime"), "HH:mm") <= to_timestamp(lit("11:59"), "HH:mm")), lit("Morning")) .when((to_timestamp(col("DepTime"), "HH:mm") >= to_timestamp(lit("12:00"), "HH:mm")) & (to_timestamp(col("DepTime"), "HH:mm") <= to_timestamp(lit("17:00"), "HH:mm")), lit("Afternoon")) .when((to_timestamp(col("DepTime"), "HH:mm") >= to_timestamp(lit("17:01"), "HH:mm")) & (to_timestamp(col("DepTime"), "HH:mm") <= to_timestamp(lit("20:00"), "HH:mm")), lit("Evening")) .otherwise(lit("Night")) )
两种方案都可以100%匹配你给出的期望输出,方案1的计算性能略优,方案2的业务规则可读性更强,可根据自己的需求选择。
内容的提问来源于stack exchange,提问作者rayqz
相关产品推荐
相关产品推荐

