Создайте новую строку для каждой минуты разницы в Spark SQL - PullRequest
2 голосов
/ 11 февраля 2020

Рассмотрим мои данные:

+---+-------------------+-------------------+
| id|          starttime|            endtime|
+---+-------------------+-------------------+
|  1|1970-01-01 07:00:00|1970-01-01 07:03:00|
+---+-------------------+-------------------+

Исходя из этого, я хочу запрос sql, который создает одну строку для каждой минуты разницы между временем окончания и временем в пути. что мои данные заканчиваются именно так:

+---+-------------------+-------------------+
| id|          starttime|            endtime|
+---+-------------------+-------------------+
|  1|1970-01-01 07:00:00|1970-01-01 07:03:00|
+---+-------------------+-------------------+
|  1|1970-01-01 07:01:00|1970-01-01 07:03:00|
+---+-------------------+-------------------+
|  1|1970-01-01 07:02:00|1970-01-01 07:03:00|
+---+-------------------+-------------------+
|  1|1970-01-01 07:03:00|1970-01-01 07:03:00|
+---+-------------------+-------------------+

У меня есть сильные предпочтения для sql, но если это невозможно, вы можете использовать pyspark.

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Попробуйте:

import pyspark.sql.functions as f
df.show()
+---+-------------------+-------------------+
| id|          starttime|            endtime|
+---+-------------------+-------------------+
|  1|1970-01-01 07:00:00|1970-01-01 07:03:00|
+---+-------------------+-------------------+

#df.printSchema()
# root
# |-- id: long (nullable = true)
# |-- starttime: timestamp (nullable = true)
# |-- endtime: timestamp (nullable = true)

Комбинация expr и sequence с интервалом в одну минуту даст вам массив меток времени в минутах, а затем explode для преобразования в строках.

df.select('id', f.explode(f.expr('sequence(starttime, endtime, interval 1 minute)')).alias('starttime'), 'endtime' ).show(truncate=False)
+---+-------------------+-------------------+
|id |starttime          |endtime            |
+---+-------------------+-------------------+
|1  |1970-01-01 07:00:00|1970-01-01 07:03:00|
|1  |1970-01-01 07:01:00|1970-01-01 07:03:00|
|1  |1970-01-01 07:02:00|1970-01-01 07:03:00|
|1  |1970-01-01 07:03:00|1970-01-01 07:03:00|
+---+-------------------+-------------------+
1 голос
/ 11 февраля 2020

Для Spark 2.4+ вы можете использовать функцию sequence, чтобы сгенерировать массив дат диапазона и затем взорвать его:

SELECT  id, 
        explode(sequence(to_timestamp(starttime), to_timestamp(endtime), interval 1 minute)) AS starttime,
        endtime
FROM    my_table


df = spark.createDataFrame([(1, "1970-01-01 07:00:00", "1970-01-01 07:03:00")], ["id", "starttime", "endtime"])
df.createOrReplaceTempView("my_table")

sql_query = """SELECT id, 
explode(sequence(to_timestamp(starttime), to_timestamp(endtime), interval 1 minute)) as starttime,
endtime
FROM my_table
"""

spark.sql(sql_query).show()

#+---+-------------------+-------------------+
#| id|          starttime|            endtime|
#+---+-------------------+-------------------+
#|  1|1970-01-01 07:00:00|1970-01-01 07:03:00|
#|  1|1970-01-01 07:01:00|1970-01-01 07:03:00|
#|  1|1970-01-01 07:02:00|1970-01-01 07:03:00|
#|  1|1970-01-01 07:03:00|1970-01-01 07:03:00|
#+---+-------------------+-------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...