繁体   English   中英

在Spark StringIndexer中处理NULL值

[英]Handling NULL values in Spark StringIndexer

我有一个带有一些分类字符串列的数据集,我想用双重类型表示它们。 我使用StringIndexer进行此转换并且它可以工作,但是当我在另一个具有NULL值的数据集中尝试它时,它给出了java.lang.NullPointerException错误并且无效。

为了更好地理解这里是我的代码:

for(col <- cols){
    out_name = col ++ "_"
    var indexer = new StringIndexer().setInputCol(col).setOutputCol(out_name)
    var indexed = indexer.fit(df).transform(df)
    df = (indexed.withColumn(col, indexed(out_name))).drop(out_name)
}

那么如何用StringIndexer解决这个NULL数据问题呢?

或者有没有更好的解决方案将字符串类型的分类数据与NULL值转换为double?

Spark> = 2.2

由于Spark 2.2 NULL值可以使用标准handleInvalid Param处理:

import org.apache.spark.ml.feature.StringIndexer

val df = Seq((0, "foo"), (1, "bar"), (2, null)).toDF("id", "label")
val indexer = new StringIndexer().setInputCol("label")

默认情况下( error )它会抛出异常:

indexer.fit(df).transform(df).show
org.apache.spark.SparkException: Failed to execute user defined function($anonfun$9: (string) => double)
  at org.apache.spark.sql.catalyst.expressions.ScalaUDF.eval(ScalaUDF.scala:1066)
...
Caused by: org.apache.spark.SparkException: StringIndexer encountered NULL value. To handle or skip NULLS, try setting StringIndexer.handleInvalid.
  at org.apache.spark.ml.feature.StringIndexerModel$$anonfun$9.apply(StringIndexer.scala:251)
...

但配置为skip

indexer.setHandleInvalid("skip").fit(df).transform(df).show
+---+-----+---------------------------+
| id|label|strIdx_46a78166054c__output|
+---+-----+---------------------------+
|  0|    a|                        0.0|
|  1|    b|                        1.0|
+---+-----+---------------------------+

keep

indexer.setHandleInvalid("keep").fit(df).transform(df).show
+---+-----+---------------------------+
| id|label|strIdx_46a78166054c__output|
+---+-----+---------------------------+
|  0|    a|                        0.0|
|  1|    b|                        1.0|
|  3| null|                        2.0|
+---+-----+---------------------------+

Spark <2.2

至于现在(Spark 1.6.1)这个问题还没有解决,但是有一个打开的JIRA( SPARK-11569 )。 不幸的是,找到一个可接受的行为并不容易。 SQL NULL表示缺失/未知值,因此任何索引都没有意义。

你可以做的最好的事情就是使用NA动作并放弃:

df.na.drop("column_to_be_indexed" :: Nil)

或填写:

df2.na.fill("__HEREBE_DRAGONS__", "column_to_be_indexed" :: Nil)

在使用索引器之前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM