Как отфильтровать столбцы даты и сохранить их как числа в кадрах данных с помощью Scala - PullRequest
0 голосов
/ 16 октября 2019

У меня есть датафрейм (dateds1), который выглядит следующим образом,

+-----------+-----------+-------------------+-------------------+
|DateofBirth|JoiningDate|      Contract Date|        ReleaseDate|
+-----------+-----------+-------------------+-------------------+
| 1995/09/16| 2008/09/09|2009-02-09 00:00:00|2017-09-09 00:00:00|
| 1994/09/20| 2008/09/10|1999-05-05 00:00:00|2016-09-30 00:00:00|
| 1993/09/24| 2016/06/29|2003-12-07 00:00:00|2028-02-13 00:00:00|
| 1992/09/28| 2007/06/24|2004-06-05 00:00:00|2019-09-24 00:00:00|
| 1991/10/03| 2011/07/07|2011-07-07 00:00:00|2020-03-30 00:00:00|
| 1990/10/07| 2009/02/09|2009-02-09 00:00:00|2011-03-13 00:00:00|
| 1989/10/11| 1999/05/05|1999-05-05 00:00:00|2021-03-13 00:00:00|

Мне нужна помощь в его фильтрации, мой вывод должен выглядеть ниже,

+-----------+-----------+-------------------+-------------------+
|DateofBirth|JoiningDate|      Contract Date|        ReleaseDate|
+-----------+-----------+-------------------+-------------------+
| 19950916  | 20080909  |20090209           |20170909           |
| 19940920  | 20080910  |19990505           |20160930           |
| 19930924  | 20160629  |20031207           |20280213           |
| 19920928  | 20070624  |20040605           |20190924           |
| 19911003  | 20110707  |20110707           |20200330           |
| 19901007  | 20090209  |20090209           |20110313           |
| 19891011  | 19990505  |19990505           |20210313           |

Я пыталсяиспользуя фильтр, но я смог отфильтровать только один из случаев, когда даты в формате ГГГГ / ММ / ДД или ГГГГ-ММ-ДД 00:00:00 и количество столбцов фиксировано. Может кто-нибудь, пожалуйста, помогите мне выяснить это для обоих форматов и когда число столбцов динамическое (они могут увеличиваться или уменьшаться). Их следует преобразовать из типа данных даты в целые или длинные в этом формате ГГГГММДД.

Примечание. Записи в этом кадре данных или в формате ГГГГ / ММ / ДД или ГГГГ-ММ-ДД 00:00:00 формат. Любая помощь приветствуется. Спасибо

1 Ответ

0 голосов
/ 16 октября 2019

Чтобы выполнить это преобразование динамически, вам придется перебирать все столбцы и выполнять различные операции в зависимости от типа столбца.

Вот пример:

import java.sql.Date
import org.apache.spark.sql.types._
import java.sql.Timestamp

val originalDf = Seq(
    (Timestamp.valueOf("2016-09-30 03:04:00"),Date.valueOf("2016-09-30")),
    (Timestamp.valueOf("2016-07-30 00:00:00"),Date.valueOf("2016-10-30"))
).toDF("ts_value","date_value")

Исходные данные таблицы:

> originalDf.show
+-------------------+----------+
|           ts_value|date_value|
+-------------------+----------+
|2016-09-30 03:04:00|2016-09-30|
|2016-07-30 00:00:00|2016-10-30|
+-------------------+----------+

> originalDf.printSchema
root
 |-- ts_value: timestamp (nullable = true)
 |-- date_value: date (nullable = true)

Пример операции преобразования:

val newDf = originalDf.columns.foldLeft(originalDf)((df, name) => {
    val data_type = df.schema(name).dataType
    if(data_type == DateType)
        df.withColumn(name, date_format(col(name), "yyyyMMdd").cast(IntegerType))
    else if(data_type == TimestampType)
        df.withColumn(name, year(col(name))*10000 + month(col(name))*100 + dayofmonth(col(name)))
    else
        df
})

Новые данные таблицы:

newDf.show
+--------+----------+
|ts_value|date_value|
+--------+----------+
|20160930|  20160930|
|20160730|  20161030|
+--------+----------+
newDf.printSchema
root
 |-- ts_value: integer (nullable = true)
 |-- date_value: integer (nullable = true)

Если вы не хотите выполнять эту операцию во всех столбцах, вы можете вручную указать столбцы, изменив

val newDf = originalDf.columns.foldLeft ...

на

val newDf = Seq("col1_name","col2_name", ... ).foldLeft ...

Hopeэто помогает!

...