8

我在PySpark中索引要素列中的字符串时出现了一个奇怪的问题。这是我的tmp.csv文件:Apache Spark在遇到缺少的功能时抛出NullPointerException

x0,x1,x2,x3 
asd2s,1e1e,1.1,0 
asd2s,1e1e,0.1,0 
,1e3e,1.2,0 
bd34t,1e1e,5.1,1 
asd2s,1e3e,0.2,0 
bd34t,1e2e,4.3,1 

其中'x0'有一个缺失值。 https://github.com/seahboonsiew/pyspark-csv 与StringIndexer然后索引X0: 起初,我使用pyspark_csv阅读从CSV文件功能集成到数据帧

import pyspark_csv as pycsv 
from pyspark.ml.feature import StringIndexer 

sc.addPyFile('pyspark_csv.py') 

features = pycsv.csvToDataFrame(sqlCtx, sc.textFile('tmp.csv')) 
indexer = StringIndexer(inputCol='x0', outputCol='x0_idx') 
ind = indexer.fit(features).transform(features) 
print ind.collect() 

调用 '' ind.collect() '' 星火抛出java.lang.NullPointerException时。一切工作正常完整的数据集,例如,'x1'虽然。

有没有人有线索是什么导致这种情况,以及如何解决它?

在此先感谢!

谢尔盖

更新:

我用星火1.5.1。确切的错误:

File "/spark/spark-1.4.1-bin-hadoop2.6/python/pyspark/sql/dataframe.py", line 258, in show 
print(self._jdf.showString(n)) 

File "/spark/spark-1.4.1-bin-hadoop2.6/python/lib/py4j-0.8.2.1-src.zip/py4j/java_gateway.py", line 538, in __call__ 

File "/spark/spark-1.4.1-bin-hadoop2.6/python/lib/py4j-0.8.2.1-src.zip/py4j/protocol.py", line 300, in get_return_value 

py4j.protocol.Py4JJavaError: An error occurred while calling o444.showString. 
: java.lang.NullPointerException 
at org.apache.spark.sql.types.Metadata$.org$apache$spark$sql$types$Metadata$$hash(Metadata.scala:208) 
at org.apache.spark.sql.types.Metadata$$anonfun$org$apache$spark$sql$types$Metadata$$hash$2.apply(Metadata.scala:196) 
at org.apache.spark.sql.types.Metadata$$anonfun$org$apache$spark$sql$types$Metadata$$hash$2.apply(Metadata.scala:196) 
... etc 

我试过不读书csv文件,以创建相同的数据帧,

df = sqlContext.createDataFrame(
    [('asd2s','1e1e',1.1,0), ('asd2s','1e1e',0.1,0), 
    (None,'1e3e',1.2,0), ('bd34t','1e1e',5.1,1), 
    ('asd2s','1e3e',0.2,0), ('bd34t','1e2e',4.3,1)], 
    ['x0','x1','x2','x3']) 

,它给了同样的错误。有一点不同的例子做工精细,

df = sqlContext.createDataFrame(
    [(0, None, 1.2), (1, '06330986ed', 2.3), 
    (2, 'b7584c2d52', 2.5), (3, None, .8), 
    (4, 'bd17e19b3a', None), (5, '51b5c0f2af', 0.1)], 
    ['id', 'x0', 'num']) 

// after indexing x0 

+---+----------+----+------+ 
| id|  x0| num|x0_idx| 
+---+----------+----+------+ 
| 0|  null| 1.2| 0.0| 
| 1|06330986ed| 2.3| 2.0| 
| 2|b7584c2d52| 2.5| 4.0| 
| 3|  null| 0.8| 0.0| 
| 4|bd17e19b3a|null| 1.0| 
| 5|51b5c0f2af| 0.1| 3.0| 
+---+----------+----+------+ 

更新2:

我刚刚发现了同样的问题在Scala中,所以我想这是星火的错误不仅PySpark。特别是,数据帧

val df = sqlContext.createDataFrame(
    Seq(("asd2s","1e1e",1.1,0), ("asd2s","1e1e",0.1,0), 
     (null,"1e3e",1.2,0), ("bd34t","1e1e",5.1,1), 
     ("asd2s","1e3e",0.2,0), ("bd34t","1e2e",4.3,1)) 
).toDF("x0","x1","x2","x3") 

索引'x0'特性时抛出java.lang.NullPointerException。此外,在以下的数据帧

val df = sqlContext.createDataFrame(
    Seq((0, null, 1.2), (1, "b", 2.3), 
     (2, "c", 2.5), (3, "a", 0.8), 
     (4, "a", null), (5, "c", 0.1)) 
).toDF("id", "x0", "num") 

我有索引“X0”何时“java.lang.UnsupportedOperationException:对于类型模式中的任何不支持”,其引起的缺少第五矢量“NUM”值。如果用一个数字代替它,即使在第一个向量中缺少值,一切都很好。

我也试过老版本的Spark(1.4.1),结果是一样的。

回答

6

它看起来像你正在使用的模块将空字符串转换为空值,并在下游处理的某个点处发生混乱。乍一看it looks like a PySpark bug

如何解决?一个简单的解决方法是滴空索引之前:

features.na.drop() 

或更换空一些占位:

from pyspark.sql.functions import col, when 

features.withColumn(
    "x0", when(col("x0").isNull(), "__SOME_PLACEHOLDER__").otherwise(col("x0"))) 

此外,您还可以使用spark-csv。这是有效的,测试和奖金不会将空字符串转换为nulls

features = (sqlContext.read 
    .format('com.databricks.spark.csv') 
    .option("inferSchema", "true") 
    .option("header", "true") 
    .load("tmp.csv")) 
0

好,目前,唯一的解决办法是让等中提出@ zero323摆脱NA的或使用toPandas()方法,以星火数据帧转换为大熊猫数据框,并使用sklearn Imputer或任何自imputer,如推诿数据,Impute categorical missing values in scikit-learn,然后将Pandas Dataframe转换回Spark DataFrame并使用它。尽管如此,问题仍然存在,我会尝试提交错误报告。我对Spark比较陌生,所以有机会我错过了一些东西。