空值

2017-05-08 30 views
1

我試圖插入數據幀到卡桑德拉:空值

result.rdd.saveToCassandra(keyspaceName, tableName) 

然而,一些列的值是空的,因此我得到異常:

java.lang.NumberFormatException: empty String 
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842) 
at sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122) 
at java.lang.Float.parseFloat(Float.java:451) 
at scala.collection.immutable.StringLike$class.toFloat(StringLike.scala:231) 
at scala.collection.immutable.StringOps.toFloat(StringOps.scala:31) 
at com.datastax.spark.connector.types.TypeConverter$FloatConverter$$anonfun$convertPF$4.applyOrElse(TypeConverter.scala:216) 

有沒有一種辦法用數據框中的空值替換所有的EMPTY值,是否可以解決這個問題? 對於這個問題,讓我們假設這是數據幀DF:

col1 | col2 | col3 
"A" | "B" | 1 
"E" | "F" | 
"S" | "K" | 5 

我如何可以替換與空COL3空值?

回答

0

如果您將DataFrame列轉換爲數字類型,則任何無法歸爲相應類型的值都將變爲空值。

import org.apache.spark.sql.types.IntegerType 
df.select(
    $"col1", 
    $"col2", 
    $"col3" cast IntegerType 
) 

,或者如果你沒有一個select語句

df.withColumn("col3", df("col3") cast IntegerType) 

如果要將此應用到,覺得它會做太不方便做這在SELECT語句中的列或者如果投射不適合您的情況,您可以轉換爲rdd以應用轉換,然後返回到數據框。你可能想爲此定義一個方法。

def emptyToNull(df: DataFrame): DataFrame = { 
    val sqlCtx = df.sqlContext 
    val schema = df.schema 

    val rdd = df.rdd.map(
     row => 
     row.toSeq.map { 
      case "" => null 
      case otherwise => otherwise 
     }) 
     .map(Row.fromSeq) 

    sqlCtx.createDataFrame(rdd, schema) 
    } 
+0

謝謝,那個變換是我在找什麼 – Ahmed

0

你可以寫這樣的udf

val df = Seq(("A", "B", "1"), ("E", "F", ""), ("S", "K", "1")).toDF("col1", "col2", "col3") 
// make a udf that converts String to option[String] 
val nullif = udf((s: String) => if(s == "") None else Some(s)) 

df.withColumn("col3", nullif($"col3")).show 

+----+----+----+ 
|col1|col2|col3| 
+----+----+----+ 
| A| B| 1| 
| E| F|null| 
| S| K| 1| 
+----+----+----+ 

您還可以使用when.otherwise,如果你想避免的UDF用法:

df.withColumn("col3", when($"col3" === "", null).otherwise($"col3")).show 

+----+----+----+ 
|col1|col2|col3| 
+----+----+----+ 
| A| B| 1| 
| E| F|null| 
| S| K| 1| 
+----+----+----+ 

或者您可以使用SQL nullif函數進行轉換ert空字符串爲空:

df.selectExpr("col1", "col2", "nullif(col3, \"\") as col3").show 
+----+----+----+ 
|col1|col2|col3| 
+----+----+----+ 
| A| B| 1| 
| E| F|null| 
| S| K| 1| 
+----+----+----+ 
+0

我希望比其他的UDF的解決方案,像有些還挺數據幀轉化,如.MAP(...) – Ahmed

+0

更新其他兩種方法用於轉換空字符串爲null。 – Psidom

+1

你的'when'例子可以簡化爲'when($「col3」!==「」$ col3「)'。'when'當沒有'otherwise'子句時默認爲null – puhlen