2015-09-25 5 views
43

DataFrameの列を任意の値(各行に同じ値)で追加したいとします。私は次のように私はwithColumnを使用するときにエラーが発生します:Spark DataFrameに定数カラムを追加するには?

dt.withColumn('new_column', 10).head(5) 

--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-50-a6d0257ca2be> in <module>() 
     1 dt = (messages 
     2  .select(messages.fromuserid, messages.messagetype, floor(messages.datetime/(1000*60*5)).alias("dt"))) 
----> 3 dt.withColumn('new_column', 10).head(5) 

/Users/evanzamir/spark-1.4.1/python/pyspark/sql/dataframe.pyc in withColumn(self, colName, col) 
    1166   [Row(age=2, name=u'Alice', age2=4), Row(age=5, name=u'Bob', age2=7)] 
    1167   """ 
-> 1168   return self.select('*', col.alias(colName)) 
    1169 
    1170  @ignore_unicode_prefix 

AttributeError: 'int' object has no attribute 'alias' 

私が追加し、他の列の1を減算してほしいと私は働いに関数をだますことができているようです(ので、彼らはゼロに追加)し、その後追加します私が望む番号(この場合は10):

dt.withColumn('new_column', dt.messagetype - dt.messagetype + 10).head(5) 

[Row(fromuserid=425, messagetype=1, dt=4809600.0, new_column=10), 
Row(fromuserid=47019141, messagetype=1, dt=4809600.0, new_column=10), 
Row(fromuserid=49746356, messagetype=1, dt=4809600.0, new_column=10), 
Row(fromuserid=93506471, messagetype=1, dt=4809600.0, new_column=10), 
Row(fromuserid=80488242, messagetype=1, dt=4809600.0, new_column=10)] 

これは非常にハッキーですよね?私はこれを行うより合法的な方法があると思いますか?

答えて

101

スパーク2.2 + 2.2紹介typedLitSeqMap、及びTuplesSPARK-19254)及びコールがサポートされるべきである以下の(スカラ)をサポートする

スパーク:

import org.apache.spark.sql.functions.typedLit 

df.withColumn("some_array", typedLit(Seq(1, 2, 3))) 
df.withColumn("some_struct", typedLit(("foo", 1, .0.3))) 
df.withColumn("some_map", typedLit(Map("key1" -> 1, "key2" -> 2))) 

スパーク1.3以降 (​​3210)、、1.4+arraystruct)、2.0+map):

DataFrame.withColumnのための二番目の引数は、そのリテラルを使用する必要がColumn次のようになります。

from pyspark.sql.functions import lit 

df.withColumn('new_column', lit(10)) 

あなたが複雑な列が必要な場合は、これらの使用してブロックを構築することができますarrayのような:

from pyspark.sql.functions import array, create_map, struct 

df.withColumn("some_array", array(lit(1), lit(2), lit(3))) 
df.withColumn("some_struct", struct(lit("foo"), lit(1), lit(.3))) 
df.withColumn("some_map", create_map(lit("key1"), lit(1), lit("key2"), lit(2))) 

全く同じ方法をScalaで使用することができます。

import org.apache.spark.sql.functions.{array, lit, map, struct} 

df.withColumn("new_column", lit(10)) 
df.withColumn("map", map(lit("key1"), lit(1), lit("key2"), lit(2))) 

UDFを使用することもできますが、遅くても可能です。

1)typedLitを使用​​3210

2)を使用して:

-1

スパーク2.2でデータフレームの列に一定の値を追加するには2つの方法があります。

この2つの違いは、typedLitもパラメータ化されたスカラ型を扱うことができることです。リスト、配列、および

サンプルDATAFRAMEマップ:NEWCOLという名前の新しい列に一定の文字列値を追加

import org.apache.spark.sql.functions.lit 
val newdf = df.withColumn("newcol",lit("myval")) 

結果:

を​​3210を使用して

val df = spark.createDataFrame(Seq((0,"a"),(1,"b"),(2,"c"))).toDF("id", "col1") 

+---+----+ 
| id|col1| 
+---+----+ 
| 0| a| 
| 1| b| 
+---+----+ 

1)

+---+----+------+ | id|col1|newcol| +---+----+------+ | 0| a| myval| | 1| b| myval| +---+----+------+ 

typedLitを使用して2):

import org.apache.spark.sql.functions.typedLit 
df.withColumn("newcol", typedLit(("sample", 10, .044))) 

結果:ダウン、それは説明を提供してください投票誰

+---+----+-----------------+ 
| id|col1|   newcol| 
+---+----+-----------------+ 
| 0| a|[sample,10,0.044]| 
| 1| b|[sample,10,0.044]| 
| 2| c|[sample,10,0.044]| 
+---+----+-----------------+ 
+0

。 –

関連する問題