web-dev-qa-db-fra.com

Conversion de l'horodatage en date dans une base de données spark

J'ai vu ici: Comment convertir Timestamp au format Date dans DataFrame? le moyen de convertir un horodatage en type de données, mais au moins pour moi, cela ne fonctionne pas.

Voici ce que j'ai essayé

# Create dataframe
df_test = spark.createDataFrame([('20170809',), ('20171007',)], ['date',])

# Convert to timestamp
df_test2 = df_test.withColumn('timestamp',func.when((df_test.date.isNull() | (df_test.date == '')) , '0')\
.otherwise(func.unix_timestamp(df_test.date,'yyyyMMdd')))\

# Convert timestamp to date again
df_test2.withColumn('date_again', df_test2['timestamp'].cast(stypes.DateType())).show()

Mais cela retourne null dans la colonne date_again:

+--------+----------+----------+
|    date| timestamp|date_again|
+--------+----------+----------+
|20170809|1502229600|      null|
|20171007|1507327200|      null|
+--------+----------+----------+

Une idée de ce qui ne va pas?

5
Luis A.G.

Suivant:

func.when((df_test.date.isNull() | (df_test.date == '')) , '0')\
  .otherwise(func.unix_timestamp(df_test.date,'yyyyMMdd'))

ne fonctionne pas car il est de type incohérent - la première clause renvoie string tandis que la deuxième clause renvoie bigint En conséquence, il retournera toujours NULL si data est NOT NULL et non vide.

Il est également obsolète - les fonctions SQL sont NULL et le format malformé est sécurisé. Il n'y a pas besoin de contrôles supplémentaires.

In [1]: spark.sql("SELECT unix_timestamp(NULL, 'yyyyMMdd')").show()
+----------------------------------------------+
|unix_timestamp(CAST(NULL AS STRING), yyyyMMdd)|
+----------------------------------------------+
|                                          null|
+----------------------------------------------+


In [2]: spark.sql("SELECT unix_timestamp('', 'yyyyMMdd')").show()
+--------------------------+
|unix_timestamp(, yyyyMMdd)|
+--------------------------+
|                      null|
+--------------------------+

Et vous n'avez pas besoin d'étape intermédiaire dans Spark 2.2 ou ultérieur:

from pyspark.sql.functions import to_date

to_date("date", "yyyyMMdd")
8
hi-zir

vous devriez faire ce qui suit 

>>> df_test2.withColumn('date_again', func.from_unixtime('timestamp').cast(DateType())).show()
+--------+----------+----------+
|    date| timestamp|date_again|
+--------+----------+----------+
|20170809|1502216100|2017-08-09|
|20171007|1507313700|2017-10-07|
+--------+----------+----------+

et le schéma est 

>>> df_test2.withColumn('date_again', func.from_unixtime('timestamp').cast(DateType())).printSchema()
root
 |-- date: string (nullable = true)
 |-- timestamp: string (nullable = true)
 |-- date_again: date (nullable = true)
9
Ramesh Maharjan

Pour pyspark:

Supposons que vous avez un nom de champ: 'DateTime' qui affiche la date en tant que date et heure

Ajoutez un nouveau champ à votre df qui affiche une colonne 'DateOnly' comme suit: 

 from pyspark.sql.functions  import date_format
    df.withColumn("DateOnly", date_format('DateTime', "yyyyMMdd")).show()

Cela montrera une nouvelle colonne dans le df appelée DateOnly - avec la date sous la forme aaaammjj 

4
Grant Shannon

Pour convertir une colonne unix_timestamp (appelée TIMESTMP) dans un cadre de données pyspark (df) - en un type Date:

Voici un processus en deux étapes (il peut y avoir un moyen plus court):

  • convertir de l'horodatage UNIX en timestamp 
  • convertir de timestamp en Date

Au départ, df.printShchema() indique: -- TIMESTMP: long (nullable = true)

utilisez spark.SQL pour implémenter la conversion comme suit:

df.registerTempTable("dfTbl")

dfNew= spark.sql("""
                     SELECT *, cast(TIMESTMP as Timestamp) as newTIMESTMP 
                     FROM dfTbl d
                  """)

dfNew.printSchema()

printSchema () affichera:

-- newTIMESTMP: timestamp (nullable = true)

convertissez enfin le type de timestamp en Date comme suit:

from pyspark.sql.types import DateType
dfNew=dfNew.withColumn('actual_date', dfNew['newTIMESTMP'].cast(DateType()))
1
Grant Shannon