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.
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
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 a
s par x
s.
In [27]: s.replace("a", "x", regex=True)
Out[27]:
0 xpe
1 monkey
2 sexgull
dtype: object
Remplacez tous les l
s par x
s.
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 a
s par x
s et l
s par p
s
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 a
s et l
s par p
s
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)