2016-02-28 43 views
1

我使用的是Spark 1.3.1,其中加入兩個數據幀重複加入的列爲 。我將左外連接兩個數據幀,並希望將結果數據幀發送到na().fill()方法,以根據列的數據類型將空值轉換爲已知的 值。我已經創建了一個 「table.column」 - >「value」的地圖並將其傳遞給fill方法。但我得到 異常,而不是成功:(我有什麼選擇?我看到有一個dataFrame.withColumnRenamed方法,但我只能重命名一個列,我有多個列連接,我只需要確保有一組唯一的列名,無論在數據幀表的別名,我申請的NA()填寫()方法問題與DataFrame na()填充方法和模糊引用

下式給出:?

scala> val df1 = sqlContext.jsonFile("people.json").as("df1") 
df1: org.apache.spark.sql.DataFrame = [first: string, last: string] 

scala> val df2 = sqlContext.jsonFile("people.json").as("df2") 
df2: org.apache.spark.sql.DataFrame = [first: string, last: string] 

我可以加入他們一起與

val df3 = df1.join(df2, df1("first") === df2("first"), "left_outer") 

而且我有一個將數據類型轉換爲值的映射。

scala> val map = Map("df1.first"->"unknown", "df1.last" -> "unknown", 
"df2.first" -> "unknown", "df2.last" -> "unknown") 

但是執行fill(map)會導致異常。

scala> df3.na.fill(map) 

org.apache.spark.sql.AnalysisException: Reference 'first' is ambiguous, 
could be: first#6, first#8.; 
+0

我敢肯定,你可以只用值來替換值,例如, 「Alberto」 - >「unknown」,「Bruce」 - >「unknown」,但不會將這些值作爲DataFrame中的位置引用,這裏是您應該看到的位置[DataFrameNaFunctions](http://spark.apache.org /docs/latest/api/scala/index.html#org.apache.spark.sql.DataFrameNaFunctions),此外我不知道你想要做什麼,如果你想替換值或重命名列,你能更加詳細一些? –

+0

我看到我的地圖不需要df1引用,這可能會導致混淆。加入後,我想用df3中的「未知」替換可能存在的空值。 na.fill()方法接受一個列 - >值對的映射,def fill(valueMap:immutable.Map [String,Any]):DataFrame。 String字段引用列名稱。 –

回答

2

這是我想出來的。在我的原始示例中,加入後df2中沒有任何有趣的內容,因此我將其更改爲經典部門/員工示例。

department.json

{"department": 2, "name":"accounting"} 
{"department": 1, "name":"engineering"} 

person.json

{"department": 1, "first":"Bruce", "last": "szalwinski"} 

現在我可以加入dataframes,建立映射,並未知數替換空值。

scala> val df1 = sqlContext.jsonFile("department.json").as("df1") 
df1: org.apache.spark.sql.DataFrame = [department: bigint, name: string] 

scala> val df2 = sqlContext.jsonFile("people.json").as("df2") 
df2: org.apache.spark.sql.DataFrame = [department: bigint, first: string, last: string] 

scala> val df3 = df1.join(df2, df1("department") === df2("department"), "left_outer") 
df3: org.apache.spark.sql.DataFrame = [department: bigint, name: string, department: bigint, first: string, last: string] 

scala> val map = Map("first" -> "unknown", "last" -> "unknown") 
map: scala.collection.immutable.Map[String,String] = Map(first -> unknown, last -> unknown) 

scala> val df4 = df3.select("df1.department", "df2.first", "df2.last").na.fill(map) 
df4: org.apache.spark.sql.DataFrame = [department: bigint, first: string, last: string] 

scala> df4.show() 
+----------+-------+----------+ 
|department| first|  last| 
+----------+-------+----------+ 
|   2|unknown| unknown| 
|   1| Bruce|szalwinski| 
+----------+-------+----------+