Pandas tipos de datos (dtype y conversión de tipos)
Pandas ofrece un sistema de tipos de datos enriquecido. Comprender y usar correctamente los tipos de datos es la base de un análisis de datos eficiente. Esta sección detalla el sistema de tipos de datos de Pandas, la inferencia de tipos y los métodos de conversión de tipos.
Descripción general de los tipos de datos de Pandas
| dtype | Descripción | Tipo de Python | Ejemplo |
|---|---|---|---|
int64 |
Entero de 64 bits | int | 1, 2, 100 |
float64 |
Flotante de 64 bits | float | 1.5, 3.14 |
object |
Cadena o tipo mixto | str | "hello" |
bool |
Booleano | bool | True, False |
datetime64[ns] |
Fecha y hora | datetime | 2024-01-01 |
timedelta64[ns] |
Diferencia de tiempo | timedelta | 1 days |
category |
Tipo categórico | - | Conjunto finito |
Ejemplos
import numpy as np
# Crear un DataFrame con varios tipos de datos
df = pd.DataFrame({
"Entero": [1, 2, 3],
"Flotante": [1.5, 2.5, 3.5],
"Cadena": ["a", "b", "c"],
"Booleano": [True, False, True],
"Fecha": pd.date_range("2024-01-01", periods=3)
})
print("Tipos de datos de cada columna:")
print(df.dtypes)
Inferencia y especificación de tipos
Inferencia automática de tipos
Ejemplos
# Inferencia de tipos al leer CSV
# pandas intenta inferir el tipo más adecuado para cada columna
df = pd.read_csv("data.csv")
# o especificar el tipo explícitamente con el parámetro dtype
df = pd.read_csv("data.csv", dtype={
"Edad": "int32", # Especificar como entero de 32 bits para ahorrar memoria
"Salario": "float32", # Especificar como flotante de 32 bits
"Nombre": "string" # Usar cadena de PyArrow
})
Especificar tipos al crear
Ejemplos
import numpy as np
# Crear una Series con un tipo de datos especificado
s = pd.Series([1, 2, 3], dtype="int8") # Usar un tipo entero más pequeño
print(f"tipo int8: {s.dtype}")
s = pd.Series([1.5, 2.5, 3.5], dtype="float32") # Usar float32
print(f"tipo float32: {s.dtype}")
# Usar tipo numpy
s = pd.Series([1, 2, 3], dtype=np.int8)
print(f"tipo np.int8: {s.dtype}")
Conversión de tipos
Convertir con astype
Ejemplos
import numpy as np
# Crear datos de ejemplo
df = pd.DataFrame({
"Entero": [1, 2, 3],
"Flotante": [1.5, 2.5, 3.5],
"Cadena": ["1", "2", "3"],
"Booleano": [1, 0, 1]
})
print("Tipos originales:")
print(df.dtypes)
print()
# Convertir a cadena
df["Entero_str"] = df["Entero"].astype(str)
print("Después de convertir a cadena:")
print(df.dtypes)
# Convertir cadena a numérico
df["Cadena_int"] = df["Cadena"].astype(int)
print("\n"Cadena a entero:")
print(df.dtypes)
# Convertir numérico a booleano (no cero es True)
df["Booleano_int"] = df["Booleano"].astype(bool)
print("\n"Entero a booleano:")
print(df.dtypes)
# Convertir flotante a entero (truncando)
df["Flotante_int"] = df["Flotante"].astype(int)
print("\n"Flotante a entero:")
print(df)
Convertir con pd.to_numeric
Ejemplos
import numpy as np
# Procesar cadenas numéricas con caracteres especiales
s = pd.Series(["$1,000", "$2,500", "$3,200"])
# Limpiar y convertir
s_cleaned = s.str.replace("$", "", regex=False).str.replace(",", "", regex=False)
s_numeric = pd.to_numeric(s_cleaned)
print("Cadena a numérico:")
print(s_numeric)
print(f"Tipo: {s_numeric.dtype}")
print()
# Manejar valores faltantes
s_with_na = pd.Series(["1", "2", "NA", "4"])
s_numeric = pd.to_numeric(s_with_na, errors="coerce") # Convertir valores no válidos a NaN
print("Manejo de valores faltantes:")
print(s_numeric)
Convertir fechas con pd.to_datetime
Ejemplos
# Conversión de varios formatos de fecha
dates = ["2024-01-01", "2024/01/02", "01/03/2024", "20240104"]
# Convertir fecha
dt = pd.to_datetime(dates, errors="coerce")
print("Resultado de la conversión de fecha:")
print(dt)
print(f"Tipo: {dt.dtype}")
print()
# Especificar el formato de fecha
dates2 = ["20240101", "20240102", "20240103"]
dt2 = pd.to_datetime(dates2, format="%Y%m%d")
print("Conversión con formato especificado:")
print(dt2)
Optimización de memoria
Elegir el tipo de datos adecuado puede reducir significativamente el uso de memoria.
Selección de tipos de enteros
Ejemplos
import numpy as np
# Crear una Series con una gran cantidad de datos
s = pd.Series(np.random.randint(0, 100, 1000000))
# int64 por defecto
print(f"Memoria int64: {s.dtype} -> {s.memory_usage(deep=True) / 1024 / 1024:.2f} MB")
# Convertir a un tipo más pequeño
s_int8 = s.astype("int8")
print(f"Memoria int8: {s_int8.dtype} -> {s_int8.memory_usage(deep=True) / 1024 / 1024:.2f} MB")
# Elegir el tipo adecuado según el rango de datos
# np.iinfo para ver el rango de enteros
print(f"\n"rango int8: {np.iinfo('int8').min} a {np.iinfo('int8').max}")
print(f"rango int16: {np.iinfo('int16').min} a {np.iinfo('int16').max}")
print(f"rango int32: {np.iinfo('int32').min} a {np.iinfo('int32').max}")
Usar el tipo category
Ejemplos
import numpy as np
# Crear una Series con muchos valores repetidos
s = pd.Series(np.random.choice(["Pekín", "Shanghái", "Guangzhou", "Shenzhen"], 1000000))
# Tipo cadena
print(f"Memoria tipo object: {s.dtype} -> {s.memory_usage(deep=True) / 1024 / 1024:.2f} MB")
# Convertir a tipo category
s_cat = s.astype("category")
print(f"Memoria tipo category: {s_cat.dtype} -> {s_cat.memory_usage(deep=True) / 1024 / 1024:.2f} MB")
# Desventaja: algunas operaciones serán más lentas
print("\n"Información de category:")
print(s_cat.cat.categories)
Comprobación y detección de tipos
Ejemplos
import numpy as np
df = pd.DataFrame({
"Entero": [1, 2, 3],
"Flotante": [1.5, 2.5, 3.5],
"Cadena": ["a", "b", "c"]
})
# Comprobar el tipo de datos
print("Comprobar si es tipo numérico:")
print(df.dtypes)
# Usar is_integer_dtype
print(f"\n"Columna entera: {pd.api.types.is_integer_dtype(df['Entero'])}")
print(f"Columna flotante: {pd.api.types.is_float_dtype(df['Flotante'])}")
print(f"Columna cadena: {pd.api.types.is_object_dtype(df['Cadena'])}")
# Comprobar si se puede convertir a numérico
print(f"\n"Se puede convertir a numérico: {pd.api.types.is_numeric_dtype(df['Entero'])}")
print(f"Es fecha y hora: {pd.api.types.is_datetime64_any_dtype(pd.Series(pd.date_range('2024', periods=3)))}")
Preguntas frecuentes
1. Aparecen flotantes en columnas de enteros
Cuando se mezclan NaN en un DataFrame, automáticamente se convierte a float64; usandoNullable Integerel tipo puede conservar los valores nulos de enteros.
2. Formatos de fecha inconsistentes
Usapd.to_datetimey especificaformatel parámetro para manejar formatos no estándar.
3. Error de tipo al leer CSV
Utilicedtypeel parámetro para especificar explícitamente el tipo, o useconverterspara realizar la conversión.
Otras extensionesPara conjuntos de datos grandes, priorice el uso de tipos de datos más pequeños (como int8, int16, float32) y tipos category para reducir el uso de memoria.