Фильтровать искровой фрейм данных с большим или меньшим из списка дат - PullRequest
0 голосов
/ 05 июня 2019

У меня есть dataframe с полями from_date и to_date:

(2017-01-10     2017-01-14)
(2017-01-03     2017-01-13)

и список дат

2017-01-05,
2017-01-12,
2017-01-13,
2017-01-15

Идея состоит в том, чтобы извлечь из таблицы все строки, в которых этот список дат находится между from_date и to_date.

Ожидаемый результат:

тот же фрейм данных, но только строки, в которых (from_date и to_date) находятся в диапазоне (<= или> =) значений списка дат. До сих пор я попробовал рекомендацию Nikk:

Фильтрация кадра данных искры с большим и меньшим из списка дат

но мне нужно сравнить со всем списком дат, что-то вроде этого:


spark.sql("select * from dataframe_table where from_date  >= (select  date from date_list) AND  to_date  <= (select date from date_list)")

Ответы [ 3 ]

0 голосов
/ 05 июня 2019

Ваш вопрос немного сбивает меня с толку, поэтому я предоставил два сценария на основе кода.

1) Если вы хотите отфильтровать даты, которые находятся в диапазоне предоставленного вами списка, например, с 5 января 2017 г.до 15 января 2017 года, поэтому для этого случая ниже приведен фрагмент кода.

//Created dataframe view for both data
    Seq(("2017-01-10", "2017-01-14"),("2017-01-03","2017-01-13")).toDF("from_date","to_date").withColumn("from_date",'from_date.cast("date")).withColumn("to_date",'to_date.cast("date")).createOrReplaceTempView("date_table")


    List("2017-01-05","2017-01-12","2017-01-13","2017-01-15").toDF("list").createOrReplaceTempView("date_list")

   spark.sql("select * from date_table where (from_date BETWEEN (select min(cast(list as date)) from date_list) and (select max(cast(list as date)) from date_list)) and (to_date between (select min(cast(list as date)) from date_list) and (select max(cast(list as date)) from date_list))").show()
    +----------+----------+
    |from_date|  to_date|
    +----------+----------+
    |2017-01-10|2017-01-14|
    +----------+----------+

2) Или если вы хотите отфильтровать дату из фрейма данных, где to_date и end_date отсутствуют в списке предоставленных дат.Таким образом, согласно приведенному вами примеру данных, между списком не будет даты.Для такого случая ниже код будет работать.

//Created dataframe view for both data
       Seq(("2017-01-10", "2017-01-14"),("2017-01-03","2017-01-13")).toDF("from_date","to_date").withColumn("from_date",'from_date.cast("date")).withColumn("to_date",'to_date.cast("date")).createOrReplaceTempView("date_table")


        List("2017-01-05","2017-01-12","2017-01-13","2017-01-15").toDF("list").createOrReplaceTempView("date_list")

        spark.sql("select * from date_table where from_date in (select cast(list as date) from date_list) and to_date in (select cast(list as date) from date_list)").show() 

    +----------+----------+
    |from_date|  to_date|
    +----------+----------+
    |            |            |
    +----------+----------+

Пожалуйста, дайте мне знать, если я что-то пропустил.

0 голосов
/ 06 июня 2019

Пожалуйста, проверьте это:

//Creating DataFrame with Column from_date and to_date, you can ignore this step if you have dataframe

scala> val df =  Seq(("2017-01-10", "2017-01-14"),("2017-01-03","2017-01-13")).toDF("from_date","to_date").withColumn("from_date", col("from_date").cast("date")).withColumn("to_date",col("to_date").cast("date"))
df: org.apache.spark.sql.DataFrame = [from_date: date, to_date: date]

scala> df.show()
+----------+----------+
| from_date|   to_date|
+----------+----------+
|2017-01-10|2017-01-14|
|2017-01-03|2017-01-13|
+----------+----------+

//creating temparary View for dataframe "df" so that we can use it in spark sql.
scala> df.createOrReplaceTempView("dataframe_table")

//Converting List into Temp view
List("2017-01-05","2017-01-12","2017-01-13","2017-01-15").toDF("list").createOrReplaceTempView("date_list")


//Query to retrive all data from dataframe where from_date and to_date are in range of list.

scala> val output =  spark.sql("select * from dataframe_table where from_date  >= (select min(cast(list as date)) from date_list) AND  to_date  <= (select max(cast(list as date)) from date_list)")
output: org.apache.spark.sql.DataFrame = [from_date: date, to_date: date]

scala> output.show()
+----------+----------+                                                         
| from_date|   to_date|
+----------+----------+
|2017-01-10|2017-01-14|
+----------+----------+
0 голосов
/ 05 июня 2019

Если вы хотите сравнить несколько строк таблицы с несколькими строками другой таблицы (давайте рассмотрим ваш список дат как таблицу с одним столбцом), вы можете использовать объединение обеих таблиц.Обычно вы проверяете столбцы таблиц на равенство.В этом случае ваш тест немного более особенный, так как вы хотите сравнить два столбца вашей первой таблицы с одним столбцом во второй.Вы можете использовать дата для этого:

scala> val df1 = Seq(("2017-01-10", "2017-01-14")).toDF("start_date","end_date").withColumn("start_date",'start_date.cast("date")).withColumn("end_date",'end_date.cast("date"))

df1: org.apache.spark.sql.DataFrame = [start_date: date, end_date: date]

scala> val df2 = Seq("2017-01-5", "2017-01-12","2017-01-13", "2017-01-15").toDF("from_date").withColumn("from_date",'from_date.cast("date"))
df2: org.apache.spark.sql.DataFrame = [from_date: date]

scala> df2.join(df1, datediff('from_date,'start_date) > 0) && datediff('from_date,'end_date) < 0)).show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...