2016-05-18 20 views
3

Ich benutze PySpark.Wie spalte ich die Spalte der Vektoren in zwei Spalten?

Spark Random Random Forest Ausgabe DataFrame hat eine Spalte "Wahrscheinlichkeit", die ein Vektor mit zwei Werten ist. Ich möchte nur zwei Spalten zum Ausgang DataFrame hinzufügen, "prob1" und "prob2", die dem ersten und zweiten Wert im Vektor entsprechen.

Ich habe versucht, die folgenden:

output2 = output.withColumn('prob1', output.map(lambda r: r['probability'][0])) 

aber ich den Fehler, dass ‚col Spalte sein sollte‘.

Irgendwelche Vorschläge, wie man eine Spalte von Vektoren in Spalten seiner Werte umwandelt?

Antwort

1

Sie können eine UDF verwenden, um den ersten Wert zu extrahieren, und eine andere, um die zweite zu extrahieren. Sie können die UDF dann mit einem Select-Aufruf für die Ausgabe des Forefront-Datenrahmens verwenden. Beispiel:

from pyspark.sql.functions import udf, col 

split1_udf = udf(lambda value: value[0], FloatType()) 
split2_udf = udf(lambda value: value[1], FloatType()) 
output2 = randomForrestOutput.select(split1_udf(col("probability")).alias("c1"), 
            split2_udf(col("probability")).alias("c2")) 

Dies sollten Sie einen Datenrahmen output2 geben, die in der Spalte Wahrscheinlichkeit gespeichert Spalten C1 und C2 entsprechend den ersten und zweiten Werte in der Liste.

+1

ich Ihren Vorschlag versucht, aber es erzeugt einen Fehler, ähnlich dem hier erwähnt: http://stackoverflow.com/questions/29910708/pyspark-py4j-pickleexception-expected-zero-arguments-for- Klassenbau – Petrichor

2

Ich habe das Problem mit dem obigen Vorschlag herausgefunden. In "pyspark" werden "dichte Vektoren einfach als NumPy-Array-Objekte dargestellt", so dass das Problem bei Python und numpy Typen liegt. Sie müssen .item() hinzufügen, um ein numpy.float64 in ein Python-Float zu konvertieren.

Der folgende Code funktioniert:

split1_udf = udf(lambda value: value[0].item(), FloatType()) 
split2_udf = udf(lambda value: value[1].item(), FloatType()) 

output2 = randomforestoutput.select(split1_udf('probability').alias('c1'), split2_udf('probability').alias('c2')) 

Oder diese Spalten auf den ursprünglichen Datenrahmen anzufügen:

randomforestoutput.withColumn('c1', split1_udf('probability')).withColumn('c2', split2_udf('probability')) 
2

das gleiche Problem Erhielt, unter der Code für die Situation angepasst ist, wenn Sie n Länge Vektor.

splits = [udf(lambda value: value[i].item(), FloatType()) for i in range(n)] 
out = tstDF.select(*[s('features').alias("Column"+str(i)) for i, s in enumerate(splits)]) 
Verwandte Themen