Apache Spark wirft NullPointerException, wenn man auf fehlende feature
Habe ich ein bizarres Problem mit PySpark, wenn die Indizierung Spalte von strings an Funktionen. Hier ist mein tmp.csv-Datei:
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
wo ich einen fehlenden Wert für 'x0'.
Auf den ersten, ich bin lese-Funktionen aus einer csv-Datei in DataFrame mit pyspark_csv: https://github.com/seahboonsiew/pyspark-csv
dann die Indizierung von x0 mit StringIndexer:
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()
beim Aufruf "ind.collect()" Funken wirft java.lang.NullPointerException. Alles funktioniert gut, für die vollständige Daten-set, z.B. für 'x1', obwohl.
Hat jemand eine Ahnung, was dies verursacht und wie man es beheben?
Vielen Dank im Voraus!
Sergey
Update:
Ich benutze Spark 1.5.1. Der genaue Fehler:
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
Ich habe versucht, erstellen Sie die gleichen DataFrame ohne Einlesen der csv-Datei,
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'])
und es gibt den gleichen Fehler. Ein etwas anderes Beispiel, funktioniert einwandfrei,
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:
Ich habe gerade entdeckt, das gleiche Thema in der Scala, so dass ich denke, es ist der Funke bug nicht PySpark nur. Insbesondere Daten-frame
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")
throws java.lang.NullPointerException bei der Indizierung von 'x0' - Funktion. Außerdem, wenn die Indizierung 'x0', in der folgenden Daten-frame
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")
Ich hab 'von java.lang.UnsupportedOperationException: Schema für Typ Any wird nicht unterstützt", die verursacht wird, durch fehlende 'num' Wert in der 5. Vektor. Ersetzt man es mit einer Zahl alles funktioniert gut, auch mit fehlender Wert in der 1. Vektor.
Ich habe auch versucht ältere Versionen von Spark (1.4.1), und das Ergebnis ist das gleiche.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sieht es aus wie Modul, die Sie verwenden leere Zeichenfolgen konvertiert, um null-Werte und es ist messing an einem gewissen Punkt mit der Weiterverarbeitung. Auf den ersten Blick es sieht aus wie ein PySpark bug.
Wie es zu lösen ist? Eine einfache Abhilfe ist, entweder löschen, null-Werte vor der Indizierung:
oder ersetzt null-Werte mit einigen Platzhalter:
Auch, Sie könnte verwenden
spark-csv
. Es ist effizient, getestet und als bonus konvertieren nicht leere Zeichenfolgen zunulls
.Gut, momentan, die einzige Lösung ist, um loszuwerden, NA wie @zero323 vorgeschlagen, zu konvertieren oder Spark DataFrame Pandas DataFrame mit toPandas () - Methode und setze die Daten mit sklearn Imputer oder benutzerdefinierte imputer, z.B., Unterstellen kategorische fehlende Werte in scikit-learn, dann konvertieren Pandas Dataframe zurück zu Spark DataFrame und mit ihm arbeiten. Trotzdem, die Frage bleibt, werde ich versuchen, einen Fehlerbericht Einreichen, falls vorhanden. Ich bin relativ neu zu entfachen, damit es eine chance gibt, bin ich etwas fehlt.