Tiene tres opciones principales para convertir tipos en pandas:
to_numeric()
- proporciona funcionalidad para convertir de forma segura tipos no numéricos (por ejemplo, cadenas) a un tipo numérico adecuado. (Ver también to_datetime()
y to_timedelta()
.)
astype()
- convierte (casi) cualquier tipo a (casi) cualquier otro tipo (incluso si no es necesariamente sensato hacerlo). También le permite convertir a tipos categoriales (muy útil).
infer_objects()
- un método de utilidad para convertir columnas de objetos que contienen objetos de Python a un tipo de pandas si es posible.
Siga leyendo para obtener explicaciones más detalladas y el uso de cada uno de estos métodos.
1) to_numeric()
La mejor manera de convertir una o más columnas de un DataFrame en valores numéricos es usar pandas.to_numeric()
.
Esta función intentará cambiar objetos no numéricos (como cadenas) en números enteros o números de coma flotante, según corresponda.
Uso básico
La entrada a to_numeric()
es una serie o una sola columna de un DataFrame.
>>> s = pd.Series(["8", 6, "7.5", 3, "0.9"]) # mixed string and numeric values
>>> s
0 8
1 6
2 7.5
3 3
4 0.9
dtype: object
>>> pd.to_numeric(s) # convert everything to float values
0 8.0
1 6.0
2 7.5
3 3.0
4 0.9
dtype: float64
Como puede ver, se devuelve una nueva serie. Recuerde asignar esta salida a una variable o nombre de columna para continuar usándola:
# convert Series
my_series = pd.to_numeric(my_series)
# convert column "a" of a DataFrame
df["a"] = pd.to_numeric(df["a"])
También puede usarlo para convertir varias columnas de un DataFrame a través del apply()
método:
# convert all columns of DataFrame
df = df.apply(pd.to_numeric) # convert all columns of DataFrame
# convert just columns "a" and "b"
df[["a", "b"]] = df[["a", "b"]].apply(pd.to_numeric)
Siempre y cuando todos sus valores se puedan convertir, eso es probablemente todo lo que necesita.
Manejo de errores
Pero, ¿qué pasa si algunos valores no se pueden convertir a un tipo numérico?
to_numeric()
también toma un errors
argumento de palabra clave que le permite forzar valores no numéricos NaN
, o simplemente ignorar las columnas que contienen estos valores.
Aquí hay un ejemplo usando una serie de cadenas s
que tiene el tipo de objeto dtype:
>>> s = pd.Series(['1', '2', '4.7', 'pandas', '10'])
>>> s
0 1
1 2
2 4.7
3 pandas
4 10
dtype: object
El comportamiento predeterminado es aumentar si no puede convertir un valor. En este caso, no puede hacer frente a la cadena 'pandas':
>>> pd.to_numeric(s) # or pd.to_numeric(s, errors='raise')
ValueError: Unable to parse string
En lugar de fallar, podríamos querer que los pandas se consideren un valor numérico faltante / incorrecto. Podemos forzar valores no válidos de la NaN
siguiente manera usando el errors
argumento de la palabra clave:
>>> pd.to_numeric(s, errors='coerce')
0 1.0
1 2.0
2 4.7
3 NaN
4 10.0
dtype: float64
La tercera opción errors
es simplemente ignorar la operación si se encuentra un valor no válido:
>>> pd.to_numeric(s, errors='ignore')
# the original Series is returned untouched
Esta última opción es particularmente útil cuando desea convertir su DataFrame completo, pero no sabe cuál de nuestras columnas se puede convertir de manera confiable a un tipo numérico. En ese caso solo escribe:
df.apply(pd.to_numeric, errors='ignore')
La función se aplicará a cada columna del DataFrame. Las columnas que se pueden convertir a un tipo numérico se convertirán, mientras que las columnas que no se pueden (por ejemplo, que contienen cadenas o fechas sin dígitos) se dejarán solas.
Abatido
Por defecto, la conversión con to_numeric()
le dará a int64
o float64
dtype (o cualquier ancho entero nativo de su plataforma).
Por lo general, eso es lo que desea, pero ¿qué sucede si desea ahorrar algo de memoria y usar un tipo de letra más compacto, como float32
, o int8
?
to_numeric()
le da la opción de bajar a 'entero', 'firmado', 'sin signo', 'flotante'. Aquí hay un ejemplo para una serie simple s
de tipo entero:
>>> s = pd.Series([1, 2, -7])
>>> s
0 1
1 2
2 -7
dtype: int64
Downcasting a 'integer' usa el entero más pequeño posible que puede contener los valores:
>>> pd.to_numeric(s, downcast='integer')
0 1
1 2
2 -7
dtype: int8
Downcasting to 'float' también elige un tipo flotante más pequeño de lo normal:
>>> pd.to_numeric(s, downcast='float')
0 1.0
1 2.0
2 -7.0
dtype: float32
2) astype()
El astype()
método le permite ser explícito sobre el tipo de letra que desea que tenga su DataFrame o Series. Es muy versátil ya que puedes probar y pasar de un tipo a otro.
Uso básico
Simplemente elija un tipo: puede usar un tipo de letra NumPy (por ejemplo np.int16
), algunos tipos de Python (por ejemplo, bool) o tipos específicos de pandas (como el tipo de letra categórico).
Llame al método en el objeto que desea convertir e astype()
intentará convertirlo por usted:
# convert all DataFrame columns to the int64 dtype
df = df.astype(int)
# convert column "a" to int64 dtype and "b" to complex type
df = df.astype({"a": int, "b": complex})
# convert Series to float16 type
s = s.astype(np.float16)
# convert Series to Python strings
s = s.astype(str)
# convert Series to categorical type - see docs for more details
s = s.astype('category')
Observe que dije "probar": si astype()
no sabe cómo convertir un valor en la Serie o el Marco de datos, generará un error. Por ejemplo, si tiene un valor NaN
o inf
obtendrá un error al intentar convertirlo en un entero.
A partir de pandas 0.20.0, este error se puede suprimir al pasar errors='ignore'
. Su objeto original será devuelto intacto.
Ten cuidado
astype()
es poderoso, pero a veces convertirá valores "incorrectamente". Por ejemplo:
>>> s = pd.Series([1, 2, -7])
>>> s
0 1
1 2
2 -7
dtype: int64
Estos son enteros pequeños, entonces, ¿qué tal si se convierte a un tipo de 8 bits sin signo para ahorrar memoria?
>>> s.astype(np.uint8)
0 1
1 2
2 249
dtype: uint8
¡La conversión funcionó, pero el -7 se envolvió para convertirse en 249 (es decir, 2 8 - 7)!
Intentar bajar el uso usando en su pd.to_numeric(s, downcast='unsigned')
lugar podría ayudar a prevenir este error.
3) infer_objects()
La versión 0.21.0 de pandas introdujo el método infer_objects()
para convertir columnas de un DataFrame que tienen un tipo de datos de objeto a un tipo más específico (conversiones suaves).
Por ejemplo, aquí hay un DataFrame con dos columnas de tipo de objeto. Uno contiene enteros reales y el otro contiene cadenas que representan enteros:
>>> df = pd.DataFrame({'a': [7, 1, 5], 'b': ['3','2','1']}, dtype='object')
>>> df.dtypes
a object
b object
dtype: object
Utilizando infer_objects()
, puede cambiar el tipo de columna 'a' a int64:
>>> df = df.infer_objects()
>>> df.dtypes
a int64
b object
dtype: object
La columna 'b' se ha dejado sola ya que sus valores eran cadenas, no enteros. Si desea tratar de forzar la conversión de ambas columnas a un tipo entero, puede usar df.astype(int)
en su lugar.