web-dev-qa-db-fra.com

Élément d'accès d'un vecteur dans un Spark DataFrame (vecteur de probabilité de régression logistique)

J'ai formé un modèle LogisticRegression dans PySpark (package ML) et le résultat de la prédiction est un PySpark DataFrame (cv_predictions) (voir [1]). La colonne probability (voir [2]) est de type vector (voir [3]).

[1]
type(cv_predictions_prod)
pyspark.sql.dataframe.DataFrame

[2]
cv_predictions_prod.select('probability').show(10, False)
+----------------------------------------+
|probability                             |
+----------------------------------------+
|[0.31559134817066054,0.6844086518293395]|
|[0.8937864350711228,0.10621356492887715]|
|[0.8615878905395029,0.1384121094604972] |
|[0.9594427633777901,0.04055723662220989]|
|[0.5391547673698157,0.46084523263018434]|
|[0.2820729747752462,0.7179270252247538] |
|[0.7730465873083118,0.22695341269168817]|
|[0.6346585276598942,0.3653414723401058] |
|[0.6346585276598942,0.3653414723401058] |
|[0.637279255218404,0.362720744781596]   |
+----------------------------------------+
only showing top 10 rows

[3]
cv_predictions_prod.printSchema()
root
 ...
 |-- rawPrediction: vector (nullable = true)
 |-- probability: vector (nullable = true)
 |-- prediction: double (nullable = true)

Comment puis-je créer une analyse du vector du PySpark DataFrame, de telle sorte que je crée une nouvelle colonne qui extrait simplement le premier élément de chaque vecteur probability?

Cette question est similaire à, mais les solutions dans les liens ci-dessous n'ont pas fonctionné/n'étaient pas claires pour moi:

Comment accéder aux valeurs de denseVector dans PySpark

Comment accéder à l'élément d'une colonne VectorUDT dans un Spark DataFrame?

17
user2205916

Mise à jour:

Il semble qu'il y ait un bug dans spark qui vous empêche d'accéder à des éléments individuels dans un vecteur dense pendant une instruction select. Normalement, vous devriez pouvoir y accéder comme vous le feriez pour un tableau numpy , mais lorsque vous essayez d'exécuter le code précédemment publié, vous pouvez obtenir l'erreur pyspark.sql.utils.AnalysisException: "Can't extract value from probability#12;"

Donc, une façon de gérer cela pour éviter ce bug idiot est d'utiliser un udf. Comme pour l'autre question, vous pouvez définir un udf de la manière suivante:

from pyspark.sql.functions import udf
from pyspark.sql.types import FloatType

firstelement=udf(lambda v:float(v[0]),FloatType())
cv_predictions_prod.select(firstelement('probability')).show()

Dans les coulisses, cela accède toujours aux éléments du DenseVector comme un tableau numpy, mais il ne lance pas le même bug qu'avant.


Étant donné que cela reçoit beaucoup de votes positifs, je me suis dit que je devrais barrer la partie incorrecte de cette réponse.

Réponse originale: Un vecteur dense n'est qu'un wrapper pour un tableau numpy. Vous pouvez donc accéder aux éléments de la même manière que vous accéderiez aux éléments d'un tableau numpy.

Il existe plusieurs façons d'accéder aux éléments individuels d'un tableau dans une trame de données. L'une consiste à appeler explicitement la colonne cv_predictions_prod['probability'] dans votre instruction select. En appelant explicitement la colonne, vous pouvez effectuer des opérations sur cette colonne, comme sélectionner le premier élément du tableau. Par exemple:

cv_predictions_prod.select(cv_predictions_prod['probability'][0]).show()

devrait résoudre le problème.

26
DavidWayne