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
R
ypython
, he visto este tipo de preguntas un par de veces.En R, tienen la función incorporada del paquete
tidyr
llamadounnest
. Pero enPython
(pandas
) no hay una función incorporada para este tipo de pregunta.Sé que las
object
columnastype
siempre hacen que los datos sean difíciles de convertir con unapandas
función '. Cuando recibí los datos de esta manera, lo primero que me vino a la mente fue 'aplanar' o desanidar las columnas.Estoy usando
pandas
ypython
funciones para este tipo de pregunta. Si le preocupa la velocidad de las soluciones anteriores, verifique la respuesta del usuario3483203, ya que está usandonumpy
y la mayoría de las vecesnumpy
es más rápido. Lo recomiendoCpython
ynumba
si 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
explode
función:Método 1
apply + pd.Series
(fácil de entender, pero no se recomienda en términos de rendimiento).Método 2
Usando
repeat
con elDataFrame
constructor, 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:
join
omerge
con elindex
después de 'desanidar' las columnas individualesSi necesita el orden de las columnas exactamente igual que antes, agréguelo
reindex
al final.Método 3
recrear el
list
Si hay más de dos columnas, utilice
Método 4
usando
reindex
oloc
Método 5
cuando la lista solo contiene valores únicos:
Método 6 que
utiliza
numpy
para un alto rendimiento:Método 7
usando la función base
itertools
cycle
ychain
: 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.DataFrame
constructor.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,
numpy
puede 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
N
columnas yM
columnas de mosaico , trabajaré más adelante para hacerlo más eficiente:Funciones
Tiempos
Actuación
fuente
df.explode
mé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
zip
o seproduct
basa en un parámetro y asume dezip
acuerdo con la longitud del objeto más largo conzip_longest
Con 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
explode
función dos veces, luego eliminando los duplicados generados y ¡hace el trabajo!fuente