web-dev-qa-db-fra.com

Python pandas équivalent pour remplacer

Dans R, il existe une fonction replace plutôt utile. Essentiellement, il effectue une réaffectation conditionnelle dans une colonne donnée d'une trame de données. Il peut être utilisé comme suit: replace(df$column, df$column==1,'Type 1');

Quelle est la bonne façon de réaliser la même chose chez les pandas?

Dois-je utiliser un lambda avec apply? (Si oui, comment puis-je obtenir une référence à la colonne donnée, par opposition à une ligne entière).

Dois-je utiliser np.where sur data_frame.values? Il semble que je manque une chose très évidente ici.

Toutes les suggestions sont appréciées.

21
ivan-k

pandas possède également une méthode replace:

In [25]: df = DataFrame({1: [2,3,4], 2: [3,4,5]})

In [26]: df
Out[26]: 
   1  2
0  2  3
1  3  4
2  4  5

In [27]: df[2]
Out[27]: 
0    3
1    4
2    5
Name: 2

In [28]: df[2].replace(4, 17)
Out[28]: 
0     3
1    17
2     5
Name: 2

In [29]: df[2].replace(4, 17, inplace=True)
Out[29]: 
0     3
1    17
2     5
Name: 2

In [30]: df
Out[30]: 
   1   2
0  2   3
1  3  17
2  4   5

ou vous pouvez utiliser l'indexation avancée de style numpy:

In [47]: df[1]
Out[47]: 
0    2
1    3
2    4
Name: 1

In [48]: df[1] == 4
Out[48]: 
0    False
1    False
2     True
Name: 1

In [49]: df[1][df[1] == 4]
Out[49]: 
2    4
Name: 1

In [50]: df[1][df[1] == 4] = 19

In [51]: df
Out[51]: 
    1   2
0   2   3
1   3  17
2  19   5
28
DSM

Doc Pandas pour replace n'a pas d'exemples, donc je vais en donner ici. Pour ceux qui viennent d'une perspective R (comme moi), replace est fondamentalement une fonction de remplacement polyvalente qui combine les fonctionnalités des fonctions R plyr::mapvalues, plyr::revalue et stringr::str_replace_all. Puisque DSM a couvert le cas des valeurs uniques, je couvrirai le cas des valeurs multiples.

Série d'exemples

In [10]: x = pd.Series([1, 2, 3, 4])

In [11]: x
Out[11]: 
0    1
1    2
2    3
3    4
dtype: int64

Nous voulons remplacer les entiers positifs par des entiers négatifs (et non en multipliant par -1).

Deux listes de valeurs

Une façon de le faire en ayant une liste (ou pandas series) des valeurs que nous voulons remplacer et une deuxième liste avec les valeurs avec lesquelles nous voulons les remplacer.

In [14]: x.replace([1, 2, 3, 4], [-1, -2, -3, -4])
Out[14]: 
0   -1
1   -2
2   -3
3   -4
dtype: int64

Cela correspond à plyr::mapvalues.

Dictionnaire des paires de valeurs

Parfois, il est plus pratique d'avoir un dictionnaire de paires de valeurs. L'index est celui que nous remplaçons et la valeur est celle avec laquelle nous le remplaçons.

In [15]: x.replace({1: -1, 2: -2, 3: -3, 4: -4})
Out[15]: 
0   -1
1   -2
2   -3
3   -4
dtype: int64

Cela correspond à plyr::revalue.

Chaînes

Il en va de même pour les chaînes, sauf que nous avons également la possibilité d'utiliser des modèles d'expression régulière.

Si nous voulons simplement remplacer les chaînes par d'autres chaînes, cela fonctionne exactement comme avant:

In [18]: s = pd.Series(["ape", "monkey", "seagull"])
In [22]: s
Out[22]: 
0        ape
1     monkey
2    seagull
dtype: object

Deux listes

In [25]: s.replace(["ape", "monkey"], ["lion", "panda"])
Out[25]: 
0       lion
1      panda
2    seagull
dtype: object

Dictionnaire

In [26]: s.replace({"ape": "lion", "monkey": "panda"})
Out[26]: 
0       lion
1      panda
2    seagull
dtype: object

Regex

Remplacez tous les as par xs.

In [27]: s.replace("a", "x", regex=True)
Out[27]: 
0        xpe
1     monkey
2    sexgull
dtype: object

Remplacez tous les ls par xs.

In [28]: s.replace("l", "x", regex=True)
Out[28]: 
0        ape
1     monkey
2    seaguxx
dtype: object

Notez que les deux l dans seagull ont été remplacés.

Remplacez as par xs et ls par ps

In [29]: s.replace(["a", "l"], ["x", "p"], regex=True)
Out[29]: 
0        xpe
1     monkey
2    sexgupp
dtype: object

Dans le cas particulier où l'on veut remplacer plusieurs valeurs différentes par la même valeur, on peut simplement utiliser une seule chaîne comme remplacement. Il ne doit pas figurer dans une liste. Remplacez as et ls par ps

In [29]: s.replace(["a", "l"], "p", regex=True)
Out[29]: 
0        ppe
1     monkey
2    sepgupp
dtype: object

(Crédit à DaveL17 dans les commentaires)

6
Deleet