4
votes

pyspark to_timestamp n'inclut pas les millisecondes

J'essaie de formater ma colonne d'horodatage pour inclure des millisecondes sans succès. Comment puis-je formater mon heure pour qu'elle ressemble à ceci - 2019-01-04 11: 09: 21.152 ?

J'ai regardé la documentation et j'ai suivi le SimpleDataTimeFormat, qui, selon la documentation pyspark, est utilisé par la fonction to_timestamp .

Ceci est mon dataframe.

>>> df.select('updated_date').withColumn("updated_date_col2", 
to_timestamp("updated_date", "YYYY-MM-dd HH:mm:ss:SSS")).show(1,False)
+--------------------------+-------------------+
|updated_date              |updated_date_col2  |
+--------------------------+-------------------+
|2019-01-04 11:09:21.152815|2019-01-04 11:09:21|
+--------------------------+-------------------+

J'utilise le format milliseconde sans succès comme ci-dessous

+--------------------------+
|updated_date              |
+--------------------------+
|2019-01-04 11:09:21.152815|
+--------------------------+

J'attends updated_date_col2 à mettre en forme comme 2019-01-04 11: 09: 21.152


1 commentaires

Le type d'horodatage n'a pas de millisecondes. Si vous le souhaitez, vous devrez conserver votre colonne sous forme de chaîne.


3 Réponses :


0
votes

Ce n'est pas une solution avec to_timestamp mais vous pouvez facilement conserver votre colonne au format heure

Le code suivant est un exemple de conversion d'une milliseconde numérique en horodatage.

from datetime import datetime

ms = datetime.now().timestamp() # ex) ms = 1547521021.83301
df = spark.createDataFrame([(1, ms)], ['obs', 'time'])
df = df.withColumn('time', df.time.cast("timestamp"))
df.show(1, False) 

+---+--------------------------+
|obs|time                      |
+---+--------------------------+
|1  |2019-01-15 12:15:49.565263|
+---+--------------------------+

si vous utilisez new Date (). getTime () ou Date.now () dans JS ou datetime.datetime.now (). timestamp () en Python, vous pouvez obtenir une milliseconde numérique.


1 commentaires

La solution ci-dessus ne fonctionne pas. je continue à recevoir un objet 'DataFrame' n'a pas d'attribut 'time' même si j'ai importé la bibliothèque datetime



0
votes

La raison pyspark to_timestamp analyse seulement jusqu'à secondes, tandis que TimestampType a la capacité de contenir des millisecondes.

La solution de contournement suivante peut fonctionner:

Si le modèle d'horodatage contient S, invoquez un UDF pour obtenir la chaîne ' INTERVAL MILLISECONDS 'à utiliser dans l'expression

df = df.withColumn(col_name, df[col_name] + expr(getIntervalStringUDF(df[my_col_name], ts_pattern)))

Pour obtenir INTERVAL 256 MILLISECONDS, nous pouvons utiliser un Java UDF:

ts_pattern = "YYYY-MM-dd HH:mm:ss:SSS"
my_col_name = "time_with_ms"

# get the time till seconds
df = df.withColumn(my_col_name, to_timestamp(df["updated_date_col2"],ts_pattern))

# add milliseconds as inteval
if 'S' in timestamp_pattern:
   df = df.withColumn(my_col_name, df[my_col_name] + expr("INTERVAL 256 MILLISECONDS"))

Inside UDF: getIntervalStringUDF (chaîne timeString, modèle de chaîne)

  1. Utilisez SimpleDateFormat pour analyser la date selon le modèle
  2. renvoie la date formatée sous forme de chaîne en utilisant le modèle "'INTERVAL' SSS 'MILLISECONDS'"
  3. renvoie 'INTERVAL 0 MILLISECONDS' sur les exceptions d'analyse / format


0 commentaires

3
votes

Je pense que vous pouvez utiliser le module datetime standard UDF et Python comme ci-dessous.

import datetime
from pyspark.sql.functions import udf
from pyspark.sql.types import TimestampType

def _to_timestamp(s):
    return datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S.%f')

udf_to_timestamp = udf(_to_timestamp, TimestampType())

df.select('updated_date').withColumn("updated_date_col2", udf_to_timestamp("updated_date")).show(1,False)


0 commentaires