Tengo el siguiente DataFrame donde una de las columnas es un objeto (celda de tipo de lista):
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]]})
df
Out[458]:
A B
0 1 [1, 2]
1 2 [1, 2]
Mi resultado esperado es:
A B
0 1 1
1 1 2
3 2 1
4 2 2
¿Qué debo hacer para lograrlo?
Pregunta relacionada
pandas: cuando el contenido de la celda sea una lista, cree una fila para cada elemento de la lista
Buena pregunta y respuesta, pero solo maneja una columna con la lista (en mi respuesta, la función de autodefinición funcionará para varias columnas, también la respuesta aceptada es la que consume más tiempo apply, lo cual no se recomienda, verifique más información ¿ Cuándo debería querer? usar pandas apply () en mi código? )

Respuestas:
Como usuario de ambos
Rypython, he visto este tipo de preguntas un par de veces.En R, tienen la función incorporada del paquete
tidyrllamadounnest. Pero enPython(pandas) no hay una función incorporada para este tipo de pregunta.Sé que las
objectcolumnastypesiempre hacen que los datos sean difíciles de convertir con unapandasfunción '. Cuando recibí los datos de esta manera, lo primero que me vino a la mente fue 'aplanar' o desanidar las columnas.Estoy usando
pandasypythonfunciones para este tipo de pregunta. Si le preocupa la velocidad de las soluciones anteriores, verifique la respuesta del usuario3483203, ya que está usandonumpyy la mayoría de las vecesnumpyes más rápido. Lo recomiendoCpythonynumbasi la velocidad importa en tu caso.Método 0 [pandas> = 0.25]
A partir de pandas 0.25 , si solo necesita expandir una columna, puede usar la
explodefunción:Método 1
apply + pd.Series(fácil de entender, pero no se recomienda en términos de rendimiento).Método 2
Usando
repeatcon elDataFrameconstructor, vuelva a crear su marco de datos (bueno en rendimiento, no bueno en múltiples columnas)Método 2.1,
por ejemplo, además de A, tenemos A.1 ..... An Si todavía usamos el método ( Método 2 ) anterior, es difícil para nosotros volver a crear las columnas una por una.
Solución:
joinomergecon elindexdespués de 'desanidar' las columnas individualesSi necesita el orden de las columnas exactamente igual que antes, agréguelo
reindexal final.Método 3
recrear el
listSi hay más de dos columnas, utilice
Método 4
usando
reindexolocMétodo 5
cuando la lista solo contiene valores únicos:
Método 6 que
utiliza
numpypara un alto rendimiento:Método 7
usando la función base
itertoolscycleychain: solución de Python pura solo por diversiónGeneralizando a múltiples columnas
Función de autodefinición:
Desanidación por columnas
Todo el método anterior está hablando de la eliminación vertical y la explosión.Si necesita gastar la lista horizontal , consulte con el
pd.DataFrameconstructor.Función actualizada
Salida de prueba
fuente
ValueError: zero-dimensional arrays cannot be concatenated. Además, pocos de estos incluso intentan generalizar a un marco de datos más amplio. Los que dicen que aún requieren que sepa cuántas columnas tiene su df de antemano.[]debe soltar, ¿realmente probó el ejemplo del mío? ¿O tienes una situación diferente?Opción 1
Si todas las sublistas de la otra columna tienen la misma longitud,
numpypuede ser una opción eficaz aquí:opcion 2
Si las sublistas tienen una longitud diferente, necesita un paso adicional:
Opción 3
Intenté generalizar esto para que funcione para aplanar
Ncolumnas yMcolumnas de mosaico , trabajaré más adelante para hacerlo más eficiente:Funciones
Tiempos
Actuación
fuente
df.explodemétodo.La explosión de una columna similar a una lista se ha simplificado significativamente en pandas 0.25 con la adición del
explode()método:Fuera:
fuente
Una alternativa es aplicar la receta meshgrid sobre las filas de las columnas para desanidar:
Salida
fuente
Mis 5 centavos:
y otros 5
ambos resultando en el mismo
fuente
Porque normalmente la longitud de las sublistas es diferente y la combinación / fusión es mucho más costosa desde el punto de vista computacional. Volví a probar el método para sublistas de diferente longitud y columnas más normales.
MultiIndex también debería ser una forma más fácil de escribir y tiene casi el mismo rendimiento que la forma numpy.
Sorprendentemente, en mi forma de implementación, la comprensión tiene el mejor rendimiento.
Actuación
Tiempo relativo de cada método
fuente
Generalicé un poco el problema para que fuera aplicable a más columnas.
Resumen de lo que hace mi solución:
Ejemplo completo:
La explosión real se realiza en 3 líneas. El resto es cosmética (explosión de varias columnas, manejo de cadenas en lugar de listas en la columna de explosión, ...).
Créditos para la respuesta de WeNYoBen
fuente
Configuración del problema
Suponga que hay varias columnas con objetos de diferente longitud dentro de ellas
Cuando las longitudes son las mismas, es fácil para nosotros asumir que los diferentes elementos coinciden y deben estar "comprimidos" juntos.
Sin embargo, la suposición se ve desafiada cuando vemos objetos de diferente longitud, deberíamos "comprimir", si es así, ¿cómo manejamos el exceso en uno de los objetos? O tal vez queramos el producto de todos los objetos. Esto crecerá rápidamente, pero podría ser lo que se desea.
O
La función
Esta función maneja con gracia
zipo seproductbasa en un parámetro y asume dezipacuerdo con la longitud del objeto más largo conzip_longestCon cremallera
Producto
Nueva configuración
Variar un poco el ejemplo
Con cremallera
Producto
fuente
Algo bastante no recomendado (al menos funciona en este caso):
concat+sort_index+iter+apply+next.Ahora:
Es:
Si le importa el índice:
Ahora:
Es:
fuente
¿Alguna opinión sobre este método que haya pensado? ¿O hacer concat y derretir se considera demasiado "caro"?
fuente
Tengo otra buena manera de resolver esto cuando tienes más de una columna para explotar.
Quiero explotar las columnas B y C. Primero exploto B, segundo C. Luego suelto B y C del df original. Después de eso, haré una unión de índice en los 3 dfs.
fuente
fuente
fuente
En mi caso, con más de una columna para explotar y con longitudes de variables para las matrices que deben anidarse.
Terminé aplicando los nuevos pandas 0.25
explodefunción dos veces, luego eliminando los duplicados generados y ¡hace el trabajo!fuente