我正在Pyspark的数据框架上工作。一列由对应于时间的整数值组成:
data.select('TIME').show(4)
+------------------+
|TIME |
+------------------+
| 925|
| 2205|
| 2205|
| 2205|
+------------------+
我希望将此时间舍入到最接近的值,时间步长为15分钟,以获得:
+------------------+
|TIME_15_MIN_STEP |
+------------------+
| 930|
| 2200|
| 2200|
| 2200|
+------------------+
有谁知道怎么做?
非常感谢!!
答案 0 :(得分:3)
一种更好的15分钟分组方法是在时间戳上使用pyspark.sql.functions.window
:
df = df \
.groupBy(F.window("timestamp", "15 minutes")) \
.withColumn("timestamp", F.col("window.start"))
请参阅文档here
答案 1 :(得分:1)
在不使用dt[,transaction := balance - shift(balance,1), by = id]
的情况下执行此操作的一种方法是首先将整数列转换为虚拟时间戳,然后执行与my answer中概述的similar question完全相同的操作}。最后将结果转换回所需格式的整数。
更全面的示例数据
我创建了一个具有更多可变性的示例来证明此方法正常工作。
udf
将整数列转换为虚拟时间戳
要将整数小时分钟列转换为时间戳,我们首先使用pyspark.sql.functions.format_string()
到add leading zeros到适当的时间。接下来,我们将一个虚拟日期(我使用data = sqlCtx.createDataFrame([(925,), (2205,), (2210,), (2242,), (2255,)], ["TIME"])
data.show()
#+----+
#|TIME|
#+----+
#| 925|
#|2205|
#|2210|
#|2242|
#|2255|
#+----+
)与转换后的时间连接起来,并在结尾添加"2018-01-01"
(几秒钟)。
":00"
计算抵消时间戳的分钟数
使用pyspark.sql.functions.minute()
从虚拟时间戳中获取分钟。我们除以15,舍入,然后乘以15得到“新”分钟。 (这个逻辑在linked answer中有更详细的解释。)
data = data.withColumn("time_string", f.format_string("%04d", f.col("TIME")))\
.withColumn(
"time_string",
f.concat_ws(
":",
f.array(
[
f.substring(
"time_string",
1,
2
),
f.substring(
"time_string",
3,
2
),
f.lit("00")
]
)
)
)\
.withColumn("time_string", f.concat(f.lit("2018-01-01 "), f.col("time_string")))
data.show()
#+----+-------------------+
#|TIME| time_string|
#+----+-------------------+
#| 925|2018-01-01 09:25:00|
#|2205|2018-01-01 22:05:00|
#|2210|2018-01-01 22:10:00|
#|2242|2018-01-01 22:42:00|
#|2255|2018-01-01 22:55:00|
#+----+-------------------+
以秒为单位添加偏移量,转换回整数
将data = data.withColumn("minute", f.minute("time_string"))\
.withColumn("new_minute", f.round(f.col("minute")/15)*15)\
.withColumn("minute_add", f.col("new_minute") - f.col("minute"))\
data.show()
#+----+-------------------+------+----------+----------+
#|TIME| time_string|minute|new_minute|minute_add|
#+----+-------------------+------+----------+----------+
#| 925|2018-01-01 09:25:00| 25| 30.0| 5.0|
#|2205|2018-01-01 22:05:00| 5| 0.0| -5.0|
#|2210|2018-01-01 22:10:00| 10| 15.0| 5.0|
#|2242|2018-01-01 22:42:00| 42| 45.0| 3.0|
#|2255|2018-01-01 22:55:00| 55| 60.0| 5.0|
#+----+-------------------+------+----------+----------+
列乘以60以获得以秒为单位的偏移量。将其添加到minute_add
以获得“新”时间。
time_string