[英]How to expand a time range into per-minute intervals in Spark (Scala or Python)?
我有一個具有以下結構的數據集。
+-------+----------+---------------+---------------+
| tv_id | movie_id | start_time | end_time |
+-------+----------+---------------+---------------+
| tv123 | movie123 | 02/05/19 3:05 | 02/05/19 3:08 |
| tv234 | movie345 | 02/05/19 3:07 | 02/05/19 3:10 |
+-------+----------+---------------+---------------+
我試圖獲得的輸出如下:
+-------+----------+---------------+
| tv_id | movie_id | minute |
+-------+----------+---------------+
| tv123 | movie123 | 02/05/19 3:05 |
| tv123 | movie123 | 02/05/19 3:06 |
| tv123 | movie123 | 02/05/19 3:07 |
| tv234 | movie345 | 02/05/19 3:07 |
| tv234 | movie345 | 02/05/19 3:08 |
| tv234 | movie345 | 02/05/19 3:09 |
+-------+----------+---------------+
詳細說明:對於tv_id:tv123,總觀看時間為3分鍾(3:08-3:05),其他記錄也是如此。
我正在嘗試使用python / Scala /或SQL來獲取結果。 [使用的語言無限制]我的python代碼:
df = read_csv('data')
df[minutes_diff] = df['end_time'] - df['start_time']
for i in range(df['minutes_diff']):
finaldf = df[tv_id] + df[movie_id] + df['start_time'] + df[minutes_diff] + "i"
我不確定該如何處理。 我不太熟悉Scala平面圖。 一些關於StackOverflow的研究指出要使用平面圖,但是我不確定如何在平面圖中使用diff來代替聚合。
注意:我不想為SQL和Python打開單獨的線程,因此將所有這些都合並在同一個問題中。 甚至一個sql解決方案對我也將是完全好的。
這是一個使用UDF的基於Scala的解決方案,該解決方案通過java.time
API將時間范圍擴展到了per-minute
列表中,然后使用Spark的內置explode
方法將其展平:
import org.apache.spark.sql.functions._
val df = Seq(
("tv123", "movie123", "02/05/19 3:05", "02/05/19 3:08"),
("tv234", "movie345", "02/05/19 3:07", "02/05/19 3:10")
).toDF("tv_id", "movie_id", "start_time", "end_time")
def minuteList(timePattern: String) = udf{ (timeS1: String, timeS2: String) =>
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
val timeFormat = DateTimeFormatter.ofPattern(timePattern)
val t1 = LocalDateTime.parse(timeS1, timeFormat)
val t2 = LocalDateTime.parse(timeS2, timeFormat)
Iterator.iterate(t1)(_.plusMinutes(1)).takeWhile(_ isBefore t2).
map(_.format(timeFormat)).
toList
}
df.
withColumn("minute_list", minuteList("MM/dd/yy H:mm")($"start_time", $"end_time")).
withColumn("minute", explode($"minute_list")).
select("tv_id", "movie_id", "minute").
show(false)
// +-----+--------+-------------+
// |tv_id|movie_id|minute |
// +-----+--------+-------------+
// |tv123|movie123|02/05/19 3:05|
// |tv123|movie123|02/05/19 3:06|
// |tv123|movie123|02/05/19 3:07|
// |tv234|movie345|02/05/19 3:07|
// |tv234|movie345|02/05/19 3:08|
// |tv234|movie345|02/05/19 3:09|
// +-----+--------+-------------+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.