web-dev-qa-db-fra.com

pyspark remplacer toutes les valeurs de la trame de données par d'autres valeurs

J'ai 500 colonnes dans mon bloc de données pyspark ... Certaines sont de type chaîne, certaines int et certaines booléennes (100 colonnes booléennes). Maintenant, toutes les colonnes booléennes ont deux niveaux distincts - Oui et Non et je veux les convertir en 1/0

Pour la chaîne, j'ai trois valeurs passées, échouées et nulles. Comment remplacer ces valeurs nulles par 0? fillna (0) ne fonctionne qu'avec des entiers

 c1| c2 |    c3 |c4|c5..... |c500
yes| yes|passed |45....
No | Yes|failed |452....
Yes|No  |None   |32............

quand je fais

df.replace(yes,1)

J'obtiens l'erreur suivante:

ValueError: Mixed type replacements are not supported
5
Emma

Pour la chaîne, j'ai trois valeurs passées, échouées et nulles. Comment remplacer ces valeurs nulles par 0? fillna (0) ne fonctionne qu'avec des entiers

Tout d'abord, importez lorsque et sont allumés

from pyspark.sql.functions import when, lit

En supposant que votre DataFrame a ces colonnes

# Reconstructing my DataFrame based on your assumptions
# cols are Columns in the DataFrame
cols = ['name', 'age', 'col_with_string']

# Similarly the values
vals = [
     ('James', 18, 'passed'),
     ('Smith', 15, 'passed'),
     ('Albie', 32, 'failed'),
     ('Stacy', 33, None),
     ('Morgan', 11, None),
     ('Dwight', 12, None),
     ('Steve', 16, 'passed'), 
     ('Shroud', 22, 'passed'),
     ('Faze', 11,'failed'),
     ('Simple', 13, None)
]

# This will create a DataFrame using 'cols' and 'vals'
# spark is an object of SparkSession
df = spark.createDataFrame(vals, cols)

# We have the following DataFrame
df.show()

+------+---+---------------+
|  name|age|col_with_string|
+------+---+---------------+
| James| 18|         passed|
| Smith| 15|         passed|
| Albie| 32|         failed|
| Stacy| 33|           null|
|Morgan| 11|           null|
|Dwight| 12|           null|
| Steve| 16|         passed|
|Shroud| 22|         passed|
|  Faze| 11|         failed|
|Simple| 13|           null|
+------+---+---------------+

Vous pouvez utiliser:

  • withColumn () - Pour spécifier la colonne que vous souhaitez utiliser.
  • isNull () - Un filtre qui évalue à vrai ssi l'attribut évalue à null
  • lit () - crée une colonne pour les littéraux
  • lorsque () , sinon () - est utilisé pour vérifier la condition par rapport à la colonne

Je peux remplacer les valeurs ayant null par 0

df = df.withColumn('col_with_string', when(df.col_with_string.isNull(), 
lit('0')).otherwise(df.col_with_string))

# We have replaced nulls with a '0'
df.show()

+------+---+---------------+
|  name|age|col_with_string|
+------+---+---------------+
| James| 18|         passed|
| Smith| 15|         passed|
| Albie| 32|         failed|
| Stacy| 33|              0|
|Morgan| 11|              0|
|Dwight| 12|              0|
| Steve| 16|         passed|
|Shroud| 22|         passed|
|  Faze| 11|         failed|
|Simple| 13|              0|
+------+---+---------------+

Partie 1 de votre question: Valeurs booléennes Oui/Non - vous l'avez mentionné, il y a 100 colonnes de booléens. Pour cela, je reconstruis généralement le tableau avec des valeurs mises à jour ou crée un UDF qui renvoie 1 ou 0 pour Oui ou Non.

J'ajoute deux autres colonnes can_vote et can_lotto au DataFrame (df)

df = df.withColumn("can_vote", col('Age') >= 18)
df = df.withColumn("can_lotto", col('Age') > 16) 

# Updated DataFrame will be
df.show()

+------+---+---------------+--------+---------+
|  name|age|col_with_string|can_vote|can_lotto|
+------+---+---------------+--------+---------+
| James| 18|         passed|    true|     true|
| Smith| 15|         passed|   false|    false|
| Albie| 32|         failed|    true|     true|
| Stacy| 33|              0|    true|     true|
|Morgan| 11|              0|   false|    false|
|Dwight| 12|              0|   false|    false|
| Steve| 16|         passed|   false|    false|
|Shroud| 22|         passed|    true|     true|
|  Faze| 11|         failed|   false|    false|
|Simple| 13|              0|   false|    false|
+------+---+---------------+--------+---------+

En supposant que vous ayez des colonnes similaires à can_vote et can_lotto (les valeurs booléennes étant Oui/Non)

Vous pouvez utiliser la ligne de code suivante pour extraire les colonnes du DataFrame de type booléen

col_with_bool = [item[0] for item in df.dtypes if item[1].startswith('boolean')]

Cela renvoie une liste

['can_vote', 'can_lotto']

Vous pouvez créer un UDF et itérer pour chaque colonne de ce type de liste, éclairer chacune des colonnes en utilisant 1 (Oui) ou 0 (Non).

Pour référence, reportez-vous aux liens suivants

1
karma4917

J'ai essayé de reproduire votre problème avec les données ci-dessous:

df_test=pd.DataFrame([['yes','pass',1.2],['No','pass',34],['yes',None,0.4],[0,1,'No'],['No',1,True],['NO','YES',1]])

alors j'utilise juste:

df_test.replace('yes',1)
2
Amine Kaddioui

Vous devriez essayer d'utiliser df.na.fill() mais en faisant la distinction entre les colonnes dans les arguments de la fonction fill.

Vous auriez quelque chose comme:

df_test.na.fill({"value":"","c4":0}).show()
0
plalanne

Vous pouvez utiliser Koalas pour faire Pandas comme des opérations dans spark. Cependant, vous devez respecter le schéma d'un cadre de données donné. En utilisant Koalas, vous pouvez faire ce qui suit:

df = df.replace('yes','1')

Une fois que vous avez remplacé toutes les chaînes en chiffres, vous pouvez convertir la colonne en int. Si vous souhaitez remplacer certaines valeurs vides par des NaN, je peux recommander de procéder comme suit:

df = df .replace(['?'], None) 
0
Horbaje