我有一些带有 "date"
列的DataFrame,我正在尝试生成一个新的DataFrame,其中包含 "date"
列的最小和最大日期之间的所有月度时间戳 .
其中一个解决方案如下:
month_step = 31*60*60*24
min_date, max_date = df.select(min_("date").cast("long"), max_("date").cast("long")).first()
df_ts = spark.range(
(min_date / month_step) * month_step,
((max_date / month_step) + 1) * month_step,
month_step
).select(col("id").cast("timestamp").alias("yearmonth"))
df_formatted_ts = df_ts.withColumn(
"yearmonth",
f.concat(f.year("yearmonth"), f.lit('-'), format_string("%02d", f.month("yearmonth")))
).select('yearmonth')
df_formatted_ts.orderBy(asc('yearmonth')).show(150, False)
问题是我花了31天时间并且它不正确,因为有些月份有30天甚至28天 . 有可能以某种方式使它更精确吗?
Just as a note :后来我只需要 year 和 month 值,所以我会忽略日期和时间 . 但无论如何,因为我在相当大的日期范围(2001年到2018年之间)生成时间戳,时间戳正在变化 .
这就是为什么有时几个月会被跳过 . 例如,2010-02缺少此快照:
|2010-01 |
|2010-03 |
|2010-04 |
|2010-05 |
|2010-06 |
|2010-07 |
我查了一下,从2001年到2018年只有3个月被忽略了 .
1 回答
假设您有以下DataFrame:
您可以按照与my answer到this question相同的方法,在
minDate
和maxDate
之间添加date
列,其中包含所有月份 .只需将
pyspark.sql.functions.datediff
替换为pyspark.sql.functions.months_between
,然后使用add_months
而不是date_add
: