8

Özelliklerde dizelerin sütunlarını indekslerken PySpark ile ilgili bir sorunum var. Ben 'x0' için bir kayıp değere sahipApache Spark, eksik özelliklerle karşılaşıldığında NullPointerException'ı atar

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 

: İşte benim tmp.csv dosyasıdır. StringIndexer ile https://github.com/seahboonsiew/pyspark-csv sonra indeksleme x0: İlk başta, pyspark_csv kullanarak DataFrame içine csv dosyasından özelliklerini okuyorum

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 '' Kıvılcım java.lang.NullPointerException atar' çağıran . Her şey, örneğin, 'x1' için olsa tam bir veri kümesi için iyi çalışır.

Buna neyin neden olduğu ve nasıl düzeltileceği konusunda bir ipucu var mı?

Şimdiden teşekkürler!

Sergey

Güncelleme:

Ben Spark 1.5.1 kullanın. Tam hata:

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 

Ben, okuma csv dosyası olmadan

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']) 

aynı DataFrame oluşturmak için denedim ve aynı hatayı veriyor. Sadece Scala aynı sorun keşfettiğinizi

, bu yüzden Kıvılcım böcek değil PySpark sadece sanırım: Biraz farklı örnek

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| 
+---+----------+----+------+ 

Update, 2 gayet iyi çalışıyor. 'X 0' özelliğini dizine Özellikle, veri çerçevesi

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") 

java.lang.NullPointerException atar.

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") 

bende aşağıdaki veriler çerçevesinde 'x0' dizine eklerken Üstelik: 5 vektöründe 'num' değeri eksik neden olan 'java.lang.UnsupportedOperationException türü için Şeması Herhangi desteklenmemektedir' . Eğer bir sayıyı bir sayı ile değiştirirse, 1. vektörde eksik değer bile olsa iyi çalışır.

Ayrıca, Spark'in (1.4.1) eski sürümlerini denedim ve sonuç aynı.

cevap

6

Kullandığınız modül boş dizeleri boş değerlere dönüştürüyor gibi görünüyor ve aşağı yönde işlemeyle bir noktada karışıyor. İlk bakışta it looks like a PySpark bug.

Nasıl düzeltilir? Basit bir geçici çözüm endeksleme önce ya damla boş değerlere şudur: bazı yer tutucu ile

features.na.drop() 

veya değiştirin nulls: Ayrıca

from pyspark.sql.functions import col, when 

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

, sen spark-csv kullanabilirsiniz.Verimli, test edilmiş ve bonus olarak boş dizeleri nulls'a dönüştürmez.

features = (sqlContext.read 
    .format('com.databricks.spark.csv') 
    .option("inferSchema", "true") 
    .option("header", "true") 
    .load("tmp.csv")) 
0
Eh @ zero323 önerilen gibi NA adlı kurtulmak için, şu anda tek çözüm olduğunu

veya toPandas() yöntemini kullanarak Pandalar DataFrame için Spark DataFrame dönüştürmek ve sklearn Imputer veya herhangi bir özel imputer, örneğin kullanarak veri impute , Impute categorical missing values in scikit-learn, daha sonra Panda Dataframe'i Spark DataFrame'e geri döndürün ve onunla çalışın. Yine de sorun devam ederse, varsa bir hata raporu göndermeyi deneyeceğim. Kıvılcım için nispeten yeniyim, bu yüzden bir şey kaçırma şansım var.