2017-04-24 12 views
0

pysparkでは、文字列としてインポートされる日付を持つデータフレームがあります。これらの日付 - 文字列の列にはヌル値があります。これらの列を日付型の列に変換しようとしていますが、エラーが発生しています。ここではデータフレームの小さな例です:Python:null値がある場合、Pyspark列を日付型に変換する方法

+--------+----------+----------+ 
|DeviceId| Created| EventDate| 
+--------+----------+----------+ 
|  1|  null|2017-03-09| 
|  1|  null|2017-03-09| 
|  1|2017-03-09|2017-03-09| 
|  1|2017-03-15|2017-03-15| 
|  1|  null|2017-05-06| 
|  1|2017-05-06|2017-05-06| 
|  1|  null|  null| 
+--------+----------+----------+ 

NULL値がない場合、私は以下のこのコードは、データ型を変換するために動作することを発見した:

dt_func = udf (lambda x: datetime.strptime(x, '%Y-%m-%d'), DateType())  
df = df.withColumn('Created', dt_func(col('Created'))) 

私はnull値にそれを追加するとクラッシュします。私は次のようにヌルを説明するために、UDFを修正しようとしました:

import numpy as np 
def convertDatetime(x): 
    return sf.when(x.isNull(), 'null').otherwise(datetime.strptime(x, '%Y-%m-%d')) 
dt_func = udf(convertDatetime, DateType()) 

私も日付に列を変換し、任意の日付文字列でヌルを埋める試みたが、その後、任意のフィル日付を交換しようとしています以下のようにヌルで:

def dt_conv(df, cols, form = '%Y-%m-%d', temp_plug = '1900-01-01'): 
    df = df.na.fill(temp_plug) 
    dt_func = udf (lambda x: datetime.strptime(x, form), DateType()) 

    for col_ in cols: 
     df = df.withColumn(col_, dt_func(col(col_))) 
    df = df.replace(datetime.strptime(temp_plug, form), 'null') 
    return df 

しかし、この方法では、私は、このエラー

ValueError: to_replace should be a float, int, long, string, list, tuple, or dict 

を与える誰かが私はこれを理解助けることができますか?

答えて

1

これを試してみてください -

# Some data, I added empty strings and nulls both 
data = [(1,'','2017-03-09'),(1,None,'2017-03-09'),(1,'2017-03-09','2017-03-09')] 

df = spark.createDataFrame(data).toDF('id','Created','EventDate') 
df.show() 

+---+----------+----------+ 
| id| Created| EventDate| 
+---+----------+----------+ 
| 1|   |2017-03-09| 
| 1|  null|2017-03-09| 
| 1|2017-03-09|2017-03-09| 
+---+----------+----------+ 

df\ 
.withColumn('Created-formatted',when((df.Created.isNull() | (df.Created == '')) ,'0')\ 
.otherwise(unix_timestamp(df.Created,'yyyy-MM-dd')))\ 
.withColumn('EventDate-formatted',when((df.EventDate.isNull() | (df.EventDate == '')) ,'0')\ 
.otherwise(unix_timestamp(df.EventDate,'yyyy-MM-dd')))\ 
.drop('Created','EventDate')\ 
.show() 

+---+-----------------+-------------------+ 
| id|Created-formatted|EventDate-formatted| 
+---+-----------------+-------------------+ 
| 1|    0|   1489035600| 
| 1|    0|   1489035600| 
| 1|  1489035600|   1489035600| 
+---+-----------------+-------------------+ 

BigInt形式を返すunix_timestampを使用しましたが、好きなようにその列を書式設定できます。

+0

unix_timestampのインポートには何が必要ですか?私は 'NameError:name 'unix_timestamp'が定義されていない 'を取得する – Jed

+0

pyspark.sql.functionsからimport unix_timestamp – Pushkr

+0

提案されたソリューションは' null'と '''値を '0'で埋めます。 '0'で塗りつぶすことなく型を変換する方法はありますか? – Jed

関連する問題