J'ai une colonne date
dans un dataframe pySpark avec des dates au format suivant:
df_new = df.withColumn( 'date1', F.to_timestamp("date", "yyyy-dd-MM'T'hh:mm:ss.s") )
Je veux convertir les dates de cette colonne de chaîne en horodatage (ou quelque chose que je peux trier en fonction de la date). Jusqu'à présent, j'ai essayé ce qui suit:
new_df = df.withColumn( 'date', from_unixtime( unix_timestamp(col(('date')), "yyyy-MM-dd'T'hh:mm:ss.SSS"), "yyyy-MM-dd'T'HH:mm:ss.SSS" ) )
et ceci
new_df = df.withColumn( 'date', unix_timestamp("date", "YYYY-MM-DD'T'hh:mm:ss.s").cast("double").cast("timestamp") )
et ceci
2018-02-01T13:13:12.023507
J'ai essayé tout ce que j'ai trouvé dans d'autres questions similaires mais jusqu'à présent, rien ne fonctionne. J'ai également essayé un format différent aaaa-MM-jj'T'HH: mm: ss.ssssss
sans succès. Que me manque-t-il?
3 Réponses :
Supposons que vous disposiez du DataFrame suivant:
from pyspark.sql.functions import split df.withColumn( 'order_column', unix_timestamp('date', "yyyy-MM-dd'T'hh:mm:ss") + split('date', "\.")[1]/1000000.0 ).sort("order_column").show(truncate=False) #+--------------------------+-------------------+ #|date |order_column | #+--------------------------+-------------------+ #|2018-02-01T13:13:12.023507|1.517508792023507E9| #|2018-02-01T13:13:12.323507|1.517508792323507E9| #+--------------------------+-------------------+
unixtimestamp
uniquement prend en charge la seconde précision . Si vous ne vous souciez que du tri basé sur la date, vous pouvez faire ce qui suit:
from pyspark.sql.functions import col, unix_timestamp df.withColumn( 'new_date', unix_timestamp(col('date'), "yyyy-MM-dd'T'hh:mm:ss").cast("timestamp") ).sort('new_date').show(truncate=False) #+--------------------------+---------------------+ #|date |new_date | #+--------------------------+---------------------+ #|2018-02-01T13:13:12.323507|2018-02-01 13:13:12.0| #|2018-02-01T13:13:12.023507|2018-02-01 13:13:12.0| #+--------------------------+---------------------+
Mais comme ces deux exemples de lignes ont la même date et heure jusqu'à la seconde , le tri ici sera indéterminé.
Si la sous-seconde partie est importante pour vous, vous pouvez écrire votre propre fonction pour gérer cela. Une façon est de diviser la colonne date
sur le .
et de diviser par 1000000.0
pour obtenir les microsecondes. Ajoutez ensuite ceci à unixtimestamp
pour le tri:
df = spark.createDataFrame( [('2018-02-01T13:13:12.023507', ), ('2018-02-01T13:13:12.323507', )], ["date"] ) df.show(truncate=False) #+--------------------------+ #|date | #+--------------------------+ #|2018-02-01T13:13:12.023507| #|2018-02-01T13:13:12.323507| #+--------------------------+
Je pense que cela devrait être de pyspark.sql.functions import col, unix_timestamp
Vous pouvez essayer udf comme ci-dessous.
format = '%Y-%m-%d %H:%M:%S:%s' func = udf (lambda x: datetime.strptime(x, format), TimestampType())
pour Spark> = 2.2 une approche alternative à unix_timestamp ()
consiste à utiliser to_timestamp()
:
from pyspark.sql.functions import col, to_timestamp new_df = df.withColumn('converted_date',to_timestamp(col('date'), "yyyy-MM-dd'T'HH:mm:ss"))