Cómo procesar datos JSON con Polars: una guía rápida
Published on
¿Sueñas con procesar datos JSON como un profesional? ¡Bienvenido a bordo! Hoy exploraremos Polars, una potente biblioteca de DataFrames en Python y Rust, con un enfoque especial en el manejo de datos JSON. Con su rendimiento ultrarrápido y sus métodos fáciles de usar, verás por qué Polars se está convirtiendo rápidamente en la opción preferida de los científicos de datos de todo el mundo.
Convertir columna de cadenas JSON en diccionario en Polars
A menudo, puedes encontrarte con un DataFrame donde una columna contiene cadenas JSON. Digamos que quieres filtrar este DataFrame basándote en claves o valores específicos dentro de estas cadenas JSON. La forma más robusta de manejar esto sería convertir las cadenas JSON en un diccionario. Sin embargo, Polars no opera con diccionarios genéricos. En su lugar, utiliza un concepto conocido como 'structs', donde cada clave del diccionario se asigna a un 'nombre de campo' de la struct, y el valor correspondiente del diccionario se convierte en el valor de este campo.
Aquí está la dificultad, crear una serie de tipo struct tiene dos restricciones principales:
- Todas las structs deben tener los mismos nombres de campos.
- Los nombres de los campos deben aparecer en el mismo orden.
¡Pero no te preocupes! Polars proporciona una función llamada json_path_match
que extrae valores basados en la sintaxis de JSONPath. Con esto, puedes verificar si una clave existe y recuperar su valor. Así es cómo puedes hacerlo:
import polars as pl
json_list = [
"""{"name": "Maria", "position": "developer", "office": "Seattle"}""",
"""{"name": "Josh", "position": "analyst", "termination_date": "2020-01-01"}""",
"""{"name": "Jorge", "position": "architect", "office": "", "manager_st_dt": "2020-01-01"}""",
]
df = pl.DataFrame(
{
"tags": json_list,
}
).with_row_count("id", 1)
df = df.with_columns([
pl.col('tags').str.json_path_match(r"$.name").alias('name'),
pl.col('tags').str.json_path_match(r"$.office").alias('location'),
pl.col('tags').str.json_path_match(r"$.manager_st_dt").alias('fecha de inicio del gerente'),
])
En el ejemplo anterior, hemos creado un DataFrame con una columna llamada 'tags' que contiene cadenas JSON. Luego usamos la función json_path_match
para extraer valores específicos. Estos valores se asignan a nuevas columnas ('name', 'location', 'fecha de inicio del gerente') en nuestro DataFrame.
Ten en cuenta que si una clave no se encuentra, json_path_match
devuelve null. Podemos utilizar este hecho para filtrar nuestro DataFrame según la presencia de una determinada clave.
df = df.filter(pl.col('tags').str.json_path_match(r"$.manager_st_dt").is_not_null())
En la línea de código anterior, estamos filtrando nuestro DataFrame para incluir solo las filas donde la clave 'manager_st_dt' está presente en la cadena JSON.
Leer archivos JSON grandes como un DataFrame en Polars
Al trabajar con archivos JSON grandes, es posible que te encuentres con el siguiente error: "EjecuciónErrónea: Error en las vinculaciones: 'ComputeError(Owned("InvalidEOF"))'". Puede haber varias razones detrás de este error, pero una causa común es que Polars intenta inferir el esquema a partir de las primeras 1000 líneas de tu archivo JSON, y luego se encuentra con un esquema diferente más adelante en el archivo. Esto suele deberse a que algunas entradas tienen claves adicionales que no estaban presentes en las primeras 1000 líneas.
Para manejar estas situaciones, podemos indicarle a Polars que utilice un esquema específico al leer el archivo, o podemos forzar a Polars a escanear todo el archivo para inferir el esquema. La segunda opción puede llevar más tiempo, especialmente para archivos grandes, pero evitará el error "InvalidEOF".
df = pl.read_json("large_file.json", infer_schema_length=None)
Al establecer infer_schema_length
en None
, obligamos a Polars a escanear todo el archivo mientras infiere el esquema. Esta operación puede llevar más tiempo, pero asegura que Polars reconozca con precisión el esquema de todo el archivo, eliminando la posibilidad de errores.
Con estas técnicas, puedes manejar tareas de procesamiento de datos JSON en Polars de manera efectiva, desde transformar cadenas JSON hasta manejar archivos JSON grandes. Polars realmente abre nuevas posibilidades para el procesamiento eficiente de datos.
Visualiza tu DataFrame de Polars con PyGWalker
PyGWalker (opens in a new tab) es una biblioteca de Python de código abierto que te ayuda a crear visualizaciones de datos a partir de tu DataFrame de Polars con facilidad.
¡Ya no necesitas completar complicados procesamientos con código Python, simplemente importa tus datos y arrastra y suelta variables para crear todo tipo de visualizaciones de datos! Aquí tienes un video demostrativo rápido sobre la operación:
Así es cómo puedes usar PyGWalker en tu Jupyter Notebook:
pip install pygwalker
import pygwalker as pyg
gwalker = pyg.walk(df)
Alternativamente, puedes probarlo en Kaggle Notebook/Google Colab:
PyGWalker se basa en el apoyo de nuestra comunidad de código abierto. ¡No olvide visitar PyGWalker GitHub (opens in a new tab) y darnos una estrella!
Preguntas Frecuentes
Aquí hay algunas preguntas frecuentes relacionadas con el manejo de datos JSON en Polars:
P: ¿Por qué necesito convertir cadenas JSON a diccionarios en Polars?
R: Polars no funciona directamente con diccionarios de Python. En cambio, utiliza el concepto de 'estructuras'. La conversión de cadenas JSON a estructuras le ayuda a realizar operaciones basadas en claves o valores específicos dentro de estas cadenas JSON.
P: ¿Qué hace el parámetro 'infer_schema_length' en la función 'read_json'?
R: El parámetro 'infer_schema_length' define cuántas líneas debe examinar Polars desde el principio de su archivo JSON para inferir su esquema. Si se establece en None
, Polars escaneará todo el archivo, lo que garantizará una comprensión exhaustiva del esquema a expensas de un tiempo de carga más largo.
P: ¿Qué sucede si no se encuentra una clave al utilizar la función 'json_path_match'?
R: Si la función 'json_path_match' no encuentra una clave, devuelve null. Este comportamiento se puede utilizar para filtrar datos en función de la presencia o ausencia de claves específicas.