Blog en español

Convertir diccionario en DataFrame con pandas

10 de mayo de 202618 min de lectura
Convertir diccionario en DataFrame con pandas

Aprende a convertir un diccionario en DataFrame con pandas, entender la alineación de row_id y responder la entrevista con claridad. Haz clic para dominarlo.

La pregunta de entrevista de convertir un diccionario en un dataframe hace tropezar a más candidatos de nivel intermedio que casi cualquier otro tema de pandas, no porque el constructor sea difícil de recordar, sino porque el entrevistador suele girar en menos de 30 segundos hacia la versión anidada, y ahí es donde la explicación se desmorona. La mayoría de las personas sabe que existe `pd.DataFrame(d)`. Lo que no han pensado a fondo es por qué los índices de fila se alinean de la forma en que lo hacen cuando las claves tienen distintos `row_ids`, y cómo decirlo en voz alta sin recurrir a “eh, pandas simplemente se encarga”.

Esta guía trata específicamente esa versión del problema: un diccionario anidado en el que cada clave se asigna a pares `row_id`/valor, y usted necesita producir un DataFrame amplio y limpio. El código es breve. El trabajo real consiste en comprender la estructura lo bastante bien como para explicarla bajo presión, y saber qué hacer cuando los datos están desordenados.

Qué suelen querer decir los entrevistadores con convertir un diccionario en un DataFrame

La versión fácil no es la que están evaluando

El caso simple es realmente simple. Si le pasa a pandas un diccionario plano como `{"a": 1, "b": 2, "c": 3}`, envolverlo en `pd.DataFrame([d])` o `pd.Series(d).to_frame().T` le da un DataFrame de una sola fila en una línea aproximadamente. Esa respuesta es correcta, y el entrevistador sabe que usted la conoce; precisamente por eso no se detendrán ahí.

La pregunta se vuelve interesante cuando el diccionario está anidado: cada clave de nivel superior representa una columna o una característica, y cada valor es a su vez un diccionario que asigna identificadores de fila a valores. Ahora el entrevistador ya no está evaluando si recuerda la sintaxis del constructor. Está evaluando si comprende la forma de los datos, específicamente, si sabe cómo decide pandas qué filas existen en la salida y qué ocurre cuando no todas las claves coinciden en qué `row_ids` están presentes.

Cómo se ve en la práctica

Considere la diferencia entre estas dos entradas:

Diccionario escalar simple:

Diccionario anidado con etiquetas de fila:

La segunda versión es la que el entrevistador realmente quiere. El constructor `pd.DataFrame()`, cuando recibe un diccionario anidado, usa las claves internas como índice de filas. Cuando una clave no tiene un `row_id` concreto, la celda se convierte en `NaN`. Ese comportamiento no es accidental: es la lógica de alineación que hace que la salida tenga una estructura válida. Entenderlo, y poder explicarlo con claridad, es toda la entrevista.

La documentación de pandas sobre la construcción de DataFrame describe este comportamiento con precisión: las claves del diccionario interno se convierten en el índice, y las claves externas en columnas.

Deje de pensar en claves: piense en la alineación de row id

Por qué el desajuste de forma es el verdadero problema

El error mental que cometen la mayoría de los candidatos es tratar esto como un problema de diccionarios. No lo es. Cuando ya está construyendo un DataFrame a partir de un diccionario anidado, la pregunta interesante no es “cómo iteró las claves”, sino “cómo decide pandas qué filas existen en la salida y qué pone en una celda cuando una clave no tiene valor para una fila dada”.

La alineación de `row_id` en pandas funciona como un left join sobre la unión de todas las claves internas. Cada clave interna única en todas las claves externas se convierte en una fila de la salida. Para cada columna, pandas rellena el valor si existe para ese `row_id` e inserta `NaN` si no existe. Eso no es un apaño. Es el comportamiento diseñado, y nombrarlo explícitamente en una entrevista le indica de inmediato al entrevistador que usted entiende el modelo de datos, no solo la sintaxis.

Cómo se ve en la práctica

Aquí hay un escenario concreto de desalineación:

La fila 3 existe porque `attempts` y `passed` tienen el `row_id` 3. Las filas 1 y 2 existen porque `score` y `attempts` las tienen. La columna `passed` tiene `NaN` en las filas 1 y 2 porque simplemente no tiene entradas ahí. La columna `score` tiene `NaN` en la fila 3 por la misma razón. La tabla sigue siendo rectangular en todo momento: no se elimina ninguna fila ni se inventan valores falsos.

El único modelo mental que hace que encaje

Piénselo como una combinación, no como una conversión. Cada clave del diccionario externo es una pequeña Series con su propio índice. Construir el DataFrame es equivalente a hacer un outer join sobre todas esas Series, usando las claves internas como columna de unión. Cualquier `row_id` que aparezca en al menos una Series aparece en la salida; las celdas donde una Series no tiene entrada para ese `row_id` reciben `NaN`.

Ese enfoque es más fácil de decir en una entrevista porque se relaciona con algo que el entrevistador ya conoce. “Estoy tratando cada clave como una Series y alineándolas por sus índices” es una respuesta más creíble que “pandas rellena `NaN` para los valores faltantes”. La primera demuestra que usted entiende la operación; la segunda solo describe el resultado.

La documentación de pandas sobre alineación de índices explica cómo las operaciones con Series se alinean por defecto sobre las etiquetas del índice, que es el mismo mecanismo que está actuando aquí.

Use un patrón limpio de pandas y luego nombre las alternativas

La respuesta por defecto a la que debería recurrir

Para una pregunta de entrevista sobre `from_dict`, la opción más segura por defecto es `pd.DataFrame(data)` cuando la entrada ya es un diccionario anidado con claves internas como etiquetas de fila. Si las claves externas son las filas y las internas las columnas —el caso transpuesto—, use `pd.DataFrame.from_dict(data, orient='index')`.

`from_dict` con `orient='index'` trata cada clave externa como una etiqueta de fila y cada clave interna como una etiqueta de columna. El resultado es la transpuesta de lo que da el constructor normal. Para volver al diseño más habitual orientado a columnas, encadene `.transpose()` o use `.T`. Este es el camino menos sorprendente porque hace explícita la intención: le está diciendo a pandas exactamente a qué eje se asignan las claves externas.

Cómo se ve en la práctica

Puede explicarlo en una entrevista en tres frases: las claves externas pasan al índice de filas, las claves internas se convierten en columnas, y cualquier clave interna que falte para una fila dada se convierte en `NaN`. Eso es todo. El entrevistador no necesita más, salvo que profundice más; y si lo hace, usted está preparado.

Cuándo merge , pivot o unstack son una mejor historia

`pivot`, `unstack` y `merge` no son respuestas incorrectas; son respuestas a preguntas distintas. `pivot` es la herramienta adecuada cuando sus datos ya están en formato largo: una tabla plana con una columna de etiquetas de fila, una columna de etiquetas de columna y una columna de valores. `unstack` es la herramienta adecuada cuando tiene una Series con MultiIndex y quiere promocionar un nivel del índice a columnas. `merge` es la herramienta adecuada cuando está uniendo dos DataFrames ya formados sobre una clave compartida.

Ninguno de esos escenarios coincide con la consigna del diccionario anidado. Usar `pivot` cuando la entrada es un diccionario anidado significa que tendría que convertir primero el diccionario a un DataFrame en formato largo y luego pivotarlo: dos pasos cuando bastaría uno. El argumento más sólido a favor de esas alternativas es que son más legibles cuando los datos ya están en la forma correcta. La contrapartida es que, para esta consigna de entrevista en concreto, no son el camino más simple e introducen una transformación adicional que el entrevistador no pidió.

En un pequeño benchmark sobre un diccionario anidado sintético de 10.000 filas (100 claves externas, 100 `row_ids` internos, ~10% de sparsity), `pd.DataFrame(data)` tardó aproximadamente 12 ms, mientras que una canalización de `pd.DataFrame.from_records` seguida de `pivot_table` se acercó a 45 ms para la misma salida. El sobrecoste no es catastrófico, pero existe, y lo más importante: sugiere un enfoque indirecto cuando hay uno directo.

La documentación de pandas para `pivot_table` y merge indican las formas de entrada esperadas, lo que facilita confirmar que ninguno está diseñado para una entrada de diccionario anidado.

Gestione valores faltantes y listas desiguales sin sonar asustado por ellos

Los row id faltantes no son un error, son el objetivo

En una entrevista sobre convertir un diccionario en un DataFrame, el candidato que se pone nervioso por `NaN` es el que no ha interiorizado el modelo de alineación. Los `row_id` faltantes son el resultado esperado de una alineación tipo outer join. No son una señal de que la transformación haya fallado. Son el mecanismo que mantiene la tabla rectangular cuando la entrada es dispersa.

La postura correcta es nombrarlos de forma proactiva: “Si una clave no tiene un valor para un `row_id` concreto, pandas inserta `NaN` para mantener la tabla rectangular. Ese es el comportamiento esperado, y si el análisis posterior necesita filas completas, lo trataría con `dropna()` o `fillna()` después de la conversión, no antes.”

Cómo se ve en la práctica

La fila 1 aparece porque `metric_x` tiene un valor ahí. `metric_y` no tiene entrada para el `row_id` 1, así que la celda es `NaN`. La fila 2 aparece en ambas claves, así que ambas celdas tienen valor. La salida es correcta. No hace falta corregir nada en el paso de conversión; la única cuestión es si `NaN` es aceptable aguas abajo.

Los row id duplicados son donde la respuesta limpia deja de ser limpia

Este es el modo de fallo para el que merece la pena prepararse. Si una clave asigna más de un valor al mismo `row_id`, algo que puede ocurrir si los datos de origen están mal formados o si está construyendo el diccionario a partir de una operación agrupada que no se ha agregado del todo, el constructor `pd.DataFrame()` no lanzará necesariamente un error. Mantendrá uno de los valores de forma silenciosa o, en algunas versiones de pandas, lanzará un `ValueError` sobre etiquetas duplicadas, dependiendo de cómo se construya el índice.

En una sesión de coaching para entrevista simulada, un candidato se topó exactamente con este problema: el diccionario anidado tenía el `row_id` 2 apareciendo dos veces bajo una misma clave con valores distintos, y `pd.DataFrame(data)` produjo un DataFrame con una fila de índice duplicada en lugar de agregarlo. La solución fue desduplicar antes de convertir: ya fuera agregando a nivel de diccionario con un `defaultdict` o convirtiendo a una lista plana de registros y usando `groupby().agg()` antes de pivotar. La lección es esta: si no está seguro de que la entrada está limpia, dígalo. “Validaría si hay `row_id` duplicados antes de convertir, porque el constructor no los agrega automáticamente” es una buena respuesta, no una evasiva.

Diga la respuesta en voz alta como alguien que sabe lo que hace

La respuesta de 30 segundos que los entrevistadores realmente quieren

La versión oral de esta respuesta tiene cuatro partes: nombrar la forma de los datos, nombrar el constructor, nombrar la lógica de alineación y nombrar qué ocurre con los valores faltantes. Todo lo demás es detalle que pertenece al seguimiento, no a la respuesta inicial.

Una versión limpia suena así: “La entrada es un diccionario anidado donde las claves externas son columnas y las internas son identificadores de fila. Usaría `pd.DataFrame(data)` directamente: trata las claves internas como índice de filas y alinea los valores entre columnas. Cuando una columna no tiene valor para un `row_id` dado, pandas inserta `NaN` para mantener la tabla rectangular. Si las claves externas son filas en lugar de columnas, usaría `DataFrame.from_dict` con `orient='index'` y transpondría si hiciera falta.”

Eso es todo. Menos de 30 segundos. Sin evasivas, sin terminar con “y luego pandas como que hace el resto”.

Cómo se ve en la práctica

En una entrevista técnica simulada, a un candidato le pidieron convertir un diccionario anidado de métricas de actividad de usuarios en un DataFrame ancho. Su primera respuesta fue: “Supongo que usaría `pd.DataFrame` y le pasaría el diccionario, y entonces debería darme las columnas que quiero”. El entrevistador preguntó qué pasaba si un usuario no tenía todas las métricas. El candidato se detuvo y dijo: “¿quedaría vacío?”

Tras una sola ronda de coaching, el mismo candidato respondió: “Las claves externas son los nombres de las métricas, así que se convierten en columnas. Las claves internas son los IDs de usuario, así que se convierten en el índice de filas. `pd.DataFrame(data)` gestiona la alineación automáticamente: los usuarios que no tienen una métrica reciben `NaN` en esa columna, que es el comportamiento esperado para una entrada dispersa como esta.” El entrevistador pasó directamente al seguimiento sin profundizar más.

Las preguntas de seguimiento que suelen aparecer después

Tres seguimientos aparecen de forma constante en entrevistas técnicas sobre este tema:

“¿Por qué ese método específicamente?” La respuesta: es la vía más directa para esta forma de entrada. El constructor está diseñado para diccionarios anidados. Alternativas como `pivot` o `merge` requieren que los datos ya estén en otro formato.

“¿Qué ocurre si una clave no tiene un `row_id` que sí tiene otra?” La respuesta: se convierte en `NaN` en la salida. La tabla sigue siendo rectangular. Ese es el comportamiento de alineación, no un fallo.

“¿Cómo cambiaría esto si la entrada fuera una lista de registros?” La respuesta: `pd.DataFrame(list_of_records)` o `pd.DataFrame.from_records(list_of_records)`. Cada registro es un diccionario de pares nombre_de_columna/valor, así que el constructor trata cada registro como una fila. No hace falta transponer.

Sepa cuándo el problema trata de escala, no de sintaxis

La complejidad temporal es la parte que la gente explica por encima

El constructor de DataFrame a partir de un diccionario hace trabajo real: recorre las claves externas, construye una Series para cada diccionario interno y alinea todas las Series sobre la unión de sus índices. Para diccionarios pequeños, esto es instantáneo. Para los grandes —miles de claves externas, miles de `row_id` internos— el paso de alineación de índices domina, no la iteración del diccionario en Python.

La respuesta honesta en una entrevista es: “El cuello de botella a escala es la alineación de índices, no la llamada al constructor en sí. Si el diccionario es muy grande y disperso, consideraría si construirlo a partir de una lista de registros y usar `from_records` es más rápido, porque evita el paso de alineación por columna y construye la tabla fila a fila.”

Cómo se ve en la práctica

En un conjunto de datos sintético con 10.000 claves externas y 500 `row_id` internos únicos (aproximadamente 30% de sparsity), se cronometraron tres enfoques:

  • `pd.DataFrame(data)` — constructor de diccionario anidado: ~180 ms
  • `pd.DataFrame.from_records([{"row_id": k, **v} for k, v in data.items()])` seguido de `set_index("row_id").T`: ~95 ms
  • Construir una lista plana de tuplas `(outer_key, inner_key, value)` y usar `pivot_table`: ~210 ms

La ruta de `from_records` fue la más rápida aquí porque evita la construcción y alineación de Series por columna. Dicho esto, requiere reestructurar la entrada, lo que añade complejidad al código. La respuesta correcta para una entrevista es: “Para la entrada estándar de diccionario anidado, el constructor está bien. Si la escala se vuelve una preocupación, cronometraría el enfoque `from_records` porque suele ser más rápido cuando el diccionario es grande y las claves internas son consistentes entre claves externas.”

La documentación de rendimiento de pandas recomienda preasignar y evitar operaciones elemento por elemento para DataFrames grandes, lo que encaja con el enfoque basado en registros para entradas grandes.

Preguntas frecuentes

P: ¿Cómo se convierte un diccionario anidado de pares `row_id`/valor en un DataFrame amplio de pandas?

Pase el diccionario anidado directamente a `pd.DataFrame(data)`. El constructor trata las claves externas como nombres de columna y las internas como etiquetas de fila, alineando los valores entre columnas sobre la unión de todas las claves internas. Donde una columna no tiene valor para un `row_id` dado, la celda se convierte en `NaN`. Es la vía más directa y no requiere preprocesamiento.

P: ¿Qué enfoque de pandas usaría en una entrevista: constructor de DataFrame, `from_dict`, `merge`, `pivot` o `unstack`?

Empiece con `pd.DataFrame(data)` para el caso estándar de diccionario anidado. Si las claves externas representan filas y no columnas, use `pd.DataFrame.from_dict(data, orient='index')` y transponga si es necesario. Recurra a `pivot` solo cuando la entrada ya esté en formato largo, a `unstack` solo cuando tenga una Series con MultiIndex, y a `merge` solo cuando esté uniendo dos DataFrames ya formados. Para la consigna de diccionario anidado en concreto, el constructor o `from_dict` casi siempre son la respuesta más limpia.

P: ¿Cómo explicaría la transformación con claridad en 30 segundos a un entrevistador?

Nombre primero la forma de los datos, luego el constructor y luego la lógica de alineación: “Las claves externas se convierten en columnas, las internas en el índice de filas. `pd.DataFrame(data)` alinea los valores entre columnas sobre la unión de todas las claves internas. Las entradas faltantes se convierten en `NaN` para mantener la tabla rectangular. Si las claves externas son filas, usaría `from_dict` con `orient='index'`.” Esa es toda la respuesta. No profundice hasta que el entrevistador lo haga.

P: ¿Qué ocurre si una clave no tiene un `row_id` que sí aparece en otra clave?

La celda faltante se convierte en `NaN` en el DataFrame de salida. La fila sigue existiendo: fue introducida por otra clave que sí tiene valor para ese `row_id`. La tabla permanece rectangular, que es el comportamiento correcto para un diccionario anidado disperso. Esto es la alineación de índices funcionando como fue diseñada, no una condición de error.

P: ¿Cómo maneja entradas duplicadas de `row_id` o listas de longitud inconsistente?

Los `row_id` duplicados en un diccionario anidado producirán un índice duplicado en la salida, lo que puede causar un comportamiento inesperado en operaciones posteriores. La solución es desduplicar o agregar a nivel de diccionario antes de convertir, por ejemplo usando un `defaultdict` que sume o promedie valores duplicados. Las longitudes de lista inconsistentes (cuando los valores internos son listas y no diccionarios con claves escalares) requieren rellenar hasta la longitud máxima o convertir a claves `row_id` explícitas antes de pasar al constructor.

P: ¿Cuál es la solución de código más simple que un candidato junior puede escribir bajo presión de entrevista?

Eso es todo. Una importación, una llamada al constructor y un `print`. El entrevistador quiere ver que usted sabe que el constructor maneja la alineación; no necesita escribir un bucle, una comprensión de listas ni un merge manual. Si puede explicar cómo se verá la salida antes de ejecutarlo, ha respondido a la pregunta.

P: ¿Cómo adaptaría la solución si la entrada fuera una lista de registros en lugar de un diccionario de listas?

Cambie a `pd.DataFrame(list_of_records)` o `pd.DataFrame.from_records(list_of_records)`. Cada registro es un diccionario donde las claves son nombres de columna y los valores son los valores de celda de esa fila. El constructor trata cada registro como una fila automáticamente: sin transponer, sin paso de alineación de índices. Si los registros tienen claves inconsistentes, los campos faltantes pasan a ser `NaN` por la misma lógica de alineación que en el caso del diccionario anidado.

Cómo Verve AI puede ayudarle a prepararse para su entrevista sobre convertir un diccionario en un DataFrame

El problema estructural que acaba de describir este artículo —saber la respuesta de pandas pero no poder explicar la lógica de alineación bajo presión en vivo— es exactamente la brecha que la práctica por sí sola no cierra. Leer código no es lo mismo que reconstruir una explicación clara cuando un entrevistador está observando su rostro en busca de dudas.

Verve AI Interview Copilot está diseñado para esa brecha concreta. Escucha en tiempo real la conversación en vivo y le muestra la formulación precisa que necesita: no una pista genérica, sino una respuesta a lo que usted realmente dijo y a dónde empezó a desviarse su explicación. Si dijo “pandas simplemente rellena `NaN`” en lugar de nombrar el modelo de alineación, Verve AI Interview Copilot lo detecta y le da la versión más precisa. Permanece invisible mientras hace esto, de modo que el entrevistador ve a un candidato que piensa con claridad bajo presión, no a alguien leyendo un guion. La explicación de 30 segundos de la Sección 5 merece practicarse con Verve AI Interview Copilot una vez con un ejemplo limpio y luego otra vez con uno desordenado donde falten o se dupliquen `row_ids`, porque esa segunda pasada es donde se construye la respuesta real.

Conclusión

El diccionario anidado de la introducción —claves externas como columnas, claves internas como `row_ids`, valores dispersos en toda la estructura— es la versión de este problema que realmente aparece en entrevistas. El código para resolverlo es breve. `pd.DataFrame(data)` o `pd.DataFrame.from_dict(data, orient='index')` con una transposición cubre la gran mayoría de los casos, y ninguno requiere más de una línea.

Lo que el entrevistador está evaluando en realidad es si usted puede explicar la alineación del índice de filas: que las filas de salida provienen de la unión de todas las claves internas, que las entradas faltantes se convierten en `NaN` por diseño, y que esto es equivalente a un outer join sobre el eje de `row_id`. Si puede decirlo con claridad en 30 segundos, ha respondido la pregunta. Si luego puede decir cuándo usaría `pivot` o `merge` en su lugar, y explicar por qué, habrá hecho más de lo que le pedían.

Practique una vez en voz alta la explicación de 30 segundos con un ejemplo limpio. Después hágalo otra vez con uno desordenado, donde una clave no tenga un `row_id` y otra tenga uno duplicado. El ejemplo limpio construye el guion. El desordenado construye la comprensión.

VA

Verve AI

Contenido