PySpark:如何从YYYY/QQ格式字符串获取季度最后一天?
从季度字符串获取季度最后一天的优化方案
针对你从「2022/4」这类格式的字符串中提取季度最后一天的需求,以下是几种比现有代码更简洁、可读性更强的实现方案:
方法一:直接利用last_day函数(最优)
PySpark的last_day函数可以直接返回指定月份的最后一天,我们只需要把季度转换为对应季度的最后一个月份,再通过该函数获取结果即可:
import pyspark.sql.functions as F df = df.withColumn( "quarter_last_day", F.last_day( F.to_date( F.concat_ws("-", # 提取年份 F.substring("period2", 1, 4), # 计算季度对应的最后一个月(如Q4对应12月) F.expr("cast(substring(period2, -1, 1) as int) * 3"), F.lit(1) ), "yyyy-MM-dd" ) ) )
这个方案逻辑最直接,没有多余的嵌套,代码量更少。
方法二:先取季度第一天,再推导最后一天
如果需要同时获取季度第一天,或者偏好更直观的分步逻辑,可以先算出季度的第一天,再通过add_months和last_day得到最后一天:
import pyspark.sql.functions as F df = df.withColumn( "quarter_first_day", F.to_date( F.concat_ws("-", F.substring("period2", 1, 4), # 计算季度对应的第一个月(如Q4对应10月) F.expr("cast(substring(period2, -1, 1) as int) * 3 - 2"), F.lit(1) ), "yyyy-MM-dd" ) ).withColumn( "quarter_last_day", # 季度第一天加2个月后,取当月最后一天 F.last_day(F.add_months(F.col("quarter_first_day"), 2)) )
方法三:简化原逻辑的嵌套
如果想保留原代码的核心思路,可以通过拆分步骤减少嵌套层级,提升可读性:
import pyspark.sql.functions as F df = df.withColumn( "quarter_first_day", F.date_trunc( "quarter", F.to_date( F.concat_ws("-", F.substring("period2", 1, 4), F.substring("period2", -1, 1), F.lit(1) ), "yyyy-MM-dd" ) ) ).withColumn( "quarter_last_day", # 季度第一天加3个月后减1天,即为季度最后一天 F.date_sub(F.add_months(F.col("quarter_first_day"), 3), 1) )
内容的提问来源于stack exchange,提问作者mdBender
相关产品推荐
相关产品推荐

