read - pandas sql python
Python pandas equivalente para reemplazar (2)
En R, hay una función de replace
bastante útil. Esencialmente, realiza una reasignación condicional en una columna dada de un marco de datos. Se puede usar como tal: replace(df$column, df$column==1,''Type 1'');
¿Cuál es una buena manera de lograr lo mismo en los pandas?
¿Debo usar un lambda con apply
? (Si es así, ¿cómo obtengo una referencia a la columna dada, en oposición a una fila completa)?
¿Debo usar np.where
en data_frame.values
? Parece que me estoy perdiendo algo muy obvio aquí.
Cualquier sugerencia es apreciada.
Pandas doc para replace
no tiene ningún ejemplo, así que daré algunos aquí. Para aquellos que vienen de una perspectiva R (como yo), replace
es básicamente una función de reemplazo de uso múltiple que combina la funcionalidad de las funciones R plyr::mapvalues
, plyr::revalue
stringr::str_replace_all
y stringr::str_replace_all
. Como DSM cubrió el caso de valores individuales, cubriré el caso de valores múltiples.
Serie ejemplo
In [10]: x = pd.Series([1, 2, 3, 4])
In [11]: x
Out[11]:
0 1
1 2
2 3
3 4
dtype: int64
Queremos reemplazar los enteros positivos con enteros negativos (y no multiplicando por -1).
Dos listas de valores
Una forma de hacerlo es tener una lista (o serie de pandas) de los valores que queremos reemplazar y una segunda lista con los valores con los que queremos reemplazarlos.
In [14]: x.replace([1, 2, 3, 4], [-1, -2, -3, -4])
Out[14]:
0 -1
1 -2
2 -3
3 -4
dtype: int64
Esto corresponde a plyr::mapvalues
.
Diccionario de pares de valores
A veces es más conveniente tener un diccionario de pares de valores. El índice es el que reemplazamos y el valor es el que reemplazamos.
In [15]: x.replace({1: -1, 2: -2, 3: -3, 4: -4})
Out[15]:
0 -1
1 -2
2 -3
3 -4
dtype: int64
Esto corresponde a plyr::revalue
.
Instrumentos de cuerda
Funciona de manera similar para cadenas, excepto que también tenemos la opción de usar patrones de expresiones regulares.
Si simplemente queremos reemplazar cadenas por otras cadenas, funciona exactamente igual que antes:
In [18]: s = pd.Series(["ape", "monkey", "seagull"])
In [22]: s
Out[22]:
0 ape
1 monkey
2 seagull
dtype: object
Dos listas
In [25]: s.replace(["ape", "monkey"], ["lion", "panda"])
Out[25]:
0 lion
1 panda
2 seagull
dtype: object
Diccionario
In [26]: s.replace({"ape": "lion", "monkey": "panda"})
Out[26]:
0 lion
1 panda
2 seagull
dtype: object
Regex
Reemplace todos los a
s con x
s.
In [27]: s.replace("a", "x", regex=True)
Out[27]:
0 xpe
1 monkey
2 sexgull
dtype: object
Reemplace todos los l
s con x
s.
In [28]: s.replace("l", "x", regex=True)
Out[28]:
0 ape
1 monkey
2 seaguxx
dtype: object
Tenga en cuenta que ambos l
s en seagull
fueron reemplazados.
Reemplaza a
s con x
s y l
s con p
s
In [29]: s.replace(["a", "l"], ["x", "p"], regex=True)
Out[29]:
0 xpe
1 monkey
2 sexgupp
dtype: object
En el caso especial en el que uno quiere reemplazar varios valores diferentes con el mismo valor, simplemente se puede usar una sola cadena como reemplazo. No debe estar dentro de una lista. Reemplace a
s y l
s con p
s
In [29]: s.replace(["a", "l"], "p", regex=True)
Out[29]:
0 ppe
1 monkey
2 sepgupp
dtype: object
(Crédito a DaveL17 en los comentarios)
pandas
tiene un método de replace
también:
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
o podrías usar la indexación avanzada de estilo 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