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?
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")
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)
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
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):
timestamp
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()))