Konvertieren Sie die pyspark-Zeichenfolge in das Datumsformat

80

Ich habe einen Datums-Pyspark-Datenrahmen mit einer Zeichenfolgenspalte im Format MM-dd-yyyyund versuche, diese in eine Datumsspalte zu konvertieren.

Ich habe es versucht:

df.select(to_date(df.STRING_COLUMN).alias('new_date')).show()

und ich bekomme eine Folge von Nullen. Kann jemand helfen?

Jenks
quelle
Sofern Sie nicht eines der TimeSeriesRDD-Addons verwenden (siehe die Spark 2016-Konferenz für einige Diskussionen, ich kenne zwei, aber beide befinden sich noch in der Entwicklung), gibt es nicht viele großartige Tools für Zeitreihen. Dementsprechend habe ich festgestellt, dass es selten einen Grund gibt, Zeichenfolgen in Datetime-Objekte zu konvertieren, wenn Ihr Ziel verschiedene Arten von groupByOperationen oder Resampling-Operationen sind. Führen Sie sie einfach für die Zeichenfolgenspalten aus.
Jeff
Die Analyse wird mit wenig bis gar keinen groupBy, sondern mit Längsschnittstudien von Krankenakten durchgeführt. Daher ist es wichtig, das Datum manipulieren zu können
Jenks

Antworten:

114

Update (10.01.2008):

Für Spark 2.2+ ist der beste Weg, dies zu tun, wahrscheinlich die Funktionen to_dateoder to_timestamp, die beide das formatArgument unterstützen. Aus den Dokumenten:

>>> from pyspark.sql.functions import to_timestamp
>>> df = spark.createDataFrame([('1997-02-28 10:30:00',)], ['t'])
>>> df.select(to_timestamp(df.t, 'yyyy-MM-dd HH:mm:ss').alias('dt')).collect()
[Row(dt=datetime.datetime(1997, 2, 28, 10, 30))]

Ursprüngliche Antwort (für Spark <2.2)

Es ist möglich (vorzuziehen?), Dies ohne udf zu tun:

from pyspark.sql.functions import unix_timestamp, from_unixtime

df = spark.createDataFrame(
    [("11/25/1991",), ("11/24/1991",), ("11/30/1991",)], 
    ['date_str']
)

df2 = df.select(
    'date_str', 
    from_unixtime(unix_timestamp('date_str', 'MM/dd/yyy')).alias('date')
)

print(df2)
#DataFrame[date_str: string, date: timestamp]

df2.show(truncate=False)
#+----------+-------------------+
#|date_str  |date               |
#+----------+-------------------+
#|11/25/1991|1991-11-25 00:00:00|
#|11/24/1991|1991-11-24 00:00:00|
#|11/30/1991|1991-11-30 00:00:00|
#+----------+-------------------+
Santon
quelle
3
Dies ist die richtige Antwort. Wenn Sie hierfür ein udf verwenden, wird Ihre Leistung beeinträchtigt.
Gberger
8
aus pyspark.sql.functions importieren from_unixtime, unix_timestamp
Quetzalcoatl
Beachten Sie, dass Sie hier eine Referenz zum Java-Datumsformat finden: docs.oracle.com/javase/6/docs/api/java/text/…
RobinL
3
Beachten Sie auch, dass to_date()mit dem Format-Argument Spark 2.2+ ist. to_dateexistierte vor 2.2, aber die
Formatoption
41
from datetime import datetime
from pyspark.sql.functions import col, udf
from pyspark.sql.types import DateType



# Creation of a dummy dataframe:
df1 = sqlContext.createDataFrame([("11/25/1991","11/24/1991","11/30/1991"), 
                            ("11/25/1391","11/24/1992","11/30/1992")], schema=['first', 'second', 'third'])

# Setting an user define function:
# This function converts the string cell into a date:
func =  udf (lambda x: datetime.strptime(x, '%m/%d/%Y'), DateType())

df = df1.withColumn('test', func(col('first')))

df.show()

df.printSchema()

Hier ist die Ausgabe:

+----------+----------+----------+----------+
|     first|    second|     third|      test|
+----------+----------+----------+----------+
|11/25/1991|11/24/1991|11/30/1991|1991-01-25|
|11/25/1391|11/24/1992|11/30/1992|1391-01-17|
+----------+----------+----------+----------+

root
 |-- first: string (nullable = true)
 |-- second: string (nullable = true)
 |-- third: string (nullable = true)
 |-- test: date (nullable = true)
Hugo Reyes
quelle
6
A udfsollte hier nicht notwendig sein, aber die eingebauten Ins, um damit umzugehen, sind grausam. Das würde ich jetzt auch tun.
Jeff
3
Warum stimmen die Daten in der Testspalte nicht mit der ersten Spalte überein? Ja, es ist jetzt vom Datumstyp, aber die Tage und Monate stimmen nicht überein. Gibt es einen Grund?
Jenks
1
Test gibt falsche Werte für Datum aus. Dies ist nicht die richtige Antwort.
Shehryar
1
Jede Lösung mit UDF ist keine Antwort, kaum eine Problemumgehung. Ich glaube nicht, dass es viele Anwendungsfälle gibt, die Sie nicht durch die Kombination von PSF und .transform () selbst tun können.
Sumon c
29

Der strptime () -Ansatz funktioniert bei mir nicht. Ich bekomme eine andere sauberere Lösung mit Cast:

from pyspark.sql.types import DateType
spark_df1 = spark_df.withColumn("record_date",spark_df['order_submitted_date'].cast(DateType()))
#below is the result
spark_df1.select('order_submitted_date','record_date').show(10,False)

+---------------------+-----------+
|order_submitted_date |record_date|
+---------------------+-----------+
|2015-08-19 12:54:16.0|2015-08-19 |
|2016-04-14 13:55:50.0|2016-04-14 |
|2013-10-11 18:23:36.0|2013-10-11 |
|2015-08-19 20:18:55.0|2015-08-19 |
|2015-08-20 12:07:40.0|2015-08-20 |
|2013-10-11 21:24:12.0|2013-10-11 |
|2013-10-11 23:29:28.0|2013-10-11 |
|2015-08-20 16:59:35.0|2015-08-20 |
|2015-08-20 17:32:03.0|2015-08-20 |
|2016-04-13 16:56:21.0|2016-04-13 |
Frank
quelle
7
Danke, dieser Ansatz hat bei mir funktioniert! Falls jemand eine Zeichenfolge wie 2008-08-01T14:45:37Zin einen Zeitstempel anstelle eines Datums konvertieren möchte , df = df.withColumn("CreationDate",df['CreationDate'].cast(TimestampType()))funktioniert dies gut ... (Spark 2.2.0)
Gaurav
1
Ich habe diese Option unter vielen von AWS Glue Pyspark ausprobiert, funktioniert wie Charme!
Abhi
10

In der Aktualisierung der akzeptierten Antwort sehen Sie das Beispiel für die to_dateFunktion nicht. Eine andere Lösung, die sie verwendet, wäre:

from pyspark.sql import functions as F

df = df.withColumn(
            'new_date',
                F.to_date(
                    F.unix_timestamp('STRINGCOLUMN', 'MM-dd-yyyy').cast('timestamp')))
Manrique
quelle
1
ein einfaches to_date () zu machen funktioniert nicht, das ist die richtige Antwort
ski_squaw
6

Möglicherweise nicht so viele Antworten, um meinen Code zu teilen, der jemandem helfen kann

from pyspark.sql import SparkSession
from pyspark.sql.functions import to_date

spark = SparkSession.builder.appName("Python Spark SQL basic example")\
    .config("spark.some.config.option", "some-value").getOrCreate()


df = spark.createDataFrame([('2019-06-22',)], ['t'])
df1 = df.select(to_date(df.t, 'yyyy-MM-dd').alias('dt'))
print df1
print df1.show()

Ausgabe

DataFrame[dt: date]
+----------+
|        dt|
+----------+
|2019-06-22|
+----------+

Der obige Code zum Konvertieren in Datum, wenn Sie Datum / Uhrzeit konvertieren möchten, verwenden Sie to_timestamp. Lassen Sie mich wissen, wenn Sie Zweifel haben.

Santosh Kumar Manda
quelle
1

Versuche dies:

df = spark.createDataFrame([('2018-07-27 10:30:00',)], ['Date_col'])
df.select(from_unixtime(unix_timestamp(df.Date_col, 'yyyy-MM-dd HH:mm:ss')).alias('dt_col'))
df.show()
+-------------------+  
|           Date_col|  
+-------------------+  
|2018-07-27 10:30:00|  
+-------------------+  
Vishwajeet Pol
quelle
6
Sie könnten darüber nachdenken, wie sich Ihre Antwort gegenüber dem, was bereits bereitgestellt und akzeptiert wurde, verbessert.
chb