2 votes

meilleure façon d'effectuer l'encodage à un coup et d'exploser la colonne avec le préfixe pyspark

J'essaie de reproduire le code de pandas dans pyspark 2.x.

Disons que j'ai un cadre de données comme suit :

    age      education    country
0   22          A          Canada
1   34          B          Mongolia
2   55          A          Peru
3   44          C          Korea

Habituellement, dans pandas, je mettrais à l'échelle les colonnes numériques et j'encoderais à chaud les colonnes catégorielles et j'obtiendrais :

    age      education_A education_B education_C    country_Canada   country_Mongolia ...
0   0            1           0           0                1                 0 
1   0.3          0           1           0                0                 0
2   1            1           0           0                0                 0         ...
3   0.7          0           0           1                ...              ...

Dans pyspark j'ai fait

str_indexer1 = StringIndexer(inputCol="education", outputCol=education+"_si", handleInvalid="skip")
str_indexer2 = StringIndexer(inputCol="country", outputCol=country+"_si", handleInvalid="skip")
mod_df = str_indexer1.fit(df).transform(df)
mod_df = str_indexer2.fit(df).transform(mod_df)

ohe1 = OneHotEncoder(inputCol="education", outputCol=education+"_ohe")
ohe2 = OneHotEncoder(inputCol="country", outputCol=country+"_ohe")

ohe1.fit(mod_df).transform(mod_df) 

Cela me donne

    age      education   country          education_si    country_si     education_ohe
0   0            A         Canada              1              1           (1,0,0,0)
1   0.3          B         Mongolia            2              2           (0,1,0,0)
2   1            A         Peru                1              3           (1,0,0,0)
3   0.7          C         Korea               3              4           (0,0,1,0)

A partir de là, je n'arrive pas à trouver comment exploser education_ohe en education_A, etc...

Comment puis-je faire cela et y a-t-il un moyen plus efficace d'exécuter ohe et scaler dans un grand dataframe ?

0voto

BrendanA Points 371

Il y a un système intégré de oneHotEncoder dans les fonctions de pyspark, mais je n'ai pas réussi à obtenir de vraies colonnes codées à un seul caractère.

Cela dit, le code suivant permet d'obtenir le résultat souhaité.

En utilisant le cadre de données suivant.

df.show()
+---+---------+--------+
|age|education| country|
+---+---------+--------+
| 22|        A|  Canada|
| 34|        B|Mongolia|
| 55|        A|    Peru|
| 44|        C|   Korea|
+---+---------+--------+

Vous pouvez sélectionner toutes les valeurs distinctes des colonnes et créer itérativement des colonnes supplémentaires.

variables_dict = {}

for col in df.columns:
    variables_dict[col] = [row[col] for row in df.distinct().collect()]

for col in variables_dict.keys():
    for val in variables_dict[col]:
        df = df.withColumn("{}_{}".format(col, val), functions.when((df[col] == val), 1).otherwise(0))

df.show()
+---+---------+--------+------+------+------+------+-----------+-----------+-----------+--------------+-------------+------------+----------------+
|age|education| country|age_22|age_44|age_55|age_34|education_A|education_C|education_B|country_Canada|country_Korea|country_Peru|country_Mongolia|
+---+---------+--------+------+------+------+------+-----------+-----------+-----------+--------------+-------------+------------+----------------+
| 22|        A|  Canada|     1|     0|     0|     0|          1|          0|          0|             1|            0|           0|               0|
| 34|        B|Mongolia|     0|     0|     0|     1|          0|          0|          1|             0|            0|           0|               1|
| 55|        A|    Peru|     0|     0|     1|     0|          1|          0|          0|             0|            0|           1|               0|
| 44|        C|   Korea|     0|     1|     0|     0|          0|          1|          0|             0|            1|           0|               0|
+---+---------+--------+------+------+------+------+-----------+-----------+-----------+--------------+-------------+------------+----------------+

Vous pouvez ensuite utiliser le même variables_dict pour appliquer le one_hot_encoder à une autre base de données.

df2.show()
+---+---------+--------+
|age|education| country|
+---+---------+--------+
| 22|        A|  Canada|
| 66|        B|Mongolia|
| 55|        D|    Peru|
| 44|        C|   China|
+---+---------+--------+

Le cadre de données ci-dessus contient des variables de colonne qui ont déjà été vues auparavant, c'est-à-dire (66, D, Chine).

Nous pouvons utiliser le code suivant pour transformer "df2" en colonnes identiques à celles de "df".

for col in variables_dict.keys():
    for val in variables_dict[col]:
        df2 = df2.withColumn("{}_{}".format(col, val), functions.when((df2[col] == val), 1).otherwise(0))

+---+---------+--------+------+------+------+------+-----------+-----------+-----------+--------------+-------------+------------+----------------+
|age|education| country|age_22|age_44|age_55|age_34|education_A|education_C|education_B|country_Canada|country_Korea|country_Peru|country_Mongolia|
+---+---------+--------+------+------+------+------+-----------+-----------+-----------+--------------+-------------+------------+----------------+
| 22|        A|  Canada|     1|     0|     0|     0|          1|          0|          0|             1|            0|           0|               0|
| 66|        B|Mongolia|     0|     0|     0|     0|          0|          0|          1|             0|            0|           0|               1|
| 55|        D|    Peru|     0|     0|     1|     0|          0|          0|          0|             0|            0|           1|               0|
| 44|        C|   China|     0|     1|     0|     0|          0|          1|          0|             0|            0|           0|               0|
+---+---------+--------+------+------+------+------+-----------+-----------+-----------+--------------+-------------+------------+----------------+

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X