2017-03-03 7 views
1

は、テストデータフレームを与える:pyspark変更日、このコードで何が間違っている

+---+--------------------+ 
| id|    date| 
+---+--------------------+ 
| a|2014-01-09 00:00:...| 
| b|2014-01-27 00:00:...| 
| c|2014-01-31 00:00:...| 
+---+--------------------+ 


root 
|-- id: string (nullable = true) 
|-- date: timestamp (nullable = true) 

それから私は、一日を変更するには、UDFを定義します日付列の:

def change_day_(date, day): 
    return date.replace(day=day) 

change_day = sf.udf(change_day_, sparktypes.TimestampType()) 
testdf.withColumn("PaidMonth", change_day(testdf.date, 1)).show(1) 

これは、エラーを発生させます

testdf.withColumn("PaidMonth", change_day(testdf.date, sf.lit(1))).show() 

代替答えは歓迎:ArthurTaccaさんのコメント@にの

Py4JError: An error occurred while calling z:org.apache.spark.sql.functions.col. Trace: 
py4j.Py4JException: Method col([class java.lang.Integer]) does not exist 
    at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:318) 
    at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:339) 
    at py4j.Gateway.invoke(Gateway.java:274) 
    at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132) 
    at py4j.commands.CallCommand.execute(CallCommand.java:79) 
    at py4j.GatewayConnection.run(GatewayConnection.java:214) 
    at java.lang.Thread.run(Thread.java:745) 
+1

おそらく 'from pyspark.sql.functions import lit'を実行した後、' lit(1) 'で' 1'( 'change_day'の呼び出しで)を置き換えてみてください。 –

+0

ありがとう!それはうまくいった! – muon

+0

@ArthurTacca理由を説明していただけますか? – muon

答えて

1

複数の引数を受け取るudfは、複数のカラムを受け取るとみなされます。 "1"は列ではありません。

これは、次のいずれかを実行できることを意味します。コメントで示唆したように、列にする次のいずれかの点灯

testdf.withColumn("PaidMonth", change_day(testdf.date, lit(1))).show(1) 

は、(1)のもの

または元の関数は、高階関数を返すように列です:

def change_day_(day): 
    return lambda date: date.replace(day=day) 

change_day = sf.udf(change_day_(1), sparktypes.TimestampType()) 
testdf.withColumn("PaidMonth", change_day(testdf.date)).show(1) 

この基本的に1で置き換えられる関数を作成し、したがって整数を受け取ることができます。 udfは単一の列に適用されます。

+0

あなたの2番目の解決策は動作しますが、日付引数がどのように渡されるか分かりません – muon

+0

関数が関数を作成します。この関数は、change_day_のdayパラメータを定数として使用します。 –

+1

@muon別の言い方をすれば、 'lit(1)'を使うと、ナンバーワンはワーカ*の 'change_day' *へのパラメータとして渡されます。この解決策では、 'change_day _()'にドライバ*の番号1 *が渡され、関数が返され、ワー​​カーに渡されます。 (2番目の関数には番号1の隠しコピーが含まれているため、最終的には番号1がすべてのワーカーに渡されます)。 –

0

おかげで、トリックは、このようpyspark.sql.functions.lit()機能を使用することです!

関連する問題