Tengo un DataFrame con muchos valores faltantes en columnas que deseo agrupar por:
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': ['1', '2', '3'], 'b': ['4', np.NaN, '6']})
In [4]: df.groupby('b').groups
Out[4]: {'4': [0], '6': [2]}
ver que Pandas ha eliminado las filas con valores objetivo de NaN. (¡Quiero incluir estas filas!)
Como necesito muchas operaciones de este tipo (muchas columnas tienen valores perdidos) y uso funciones más complicadas que solo medianas (generalmente bosques aleatorios), quiero evitar escribir fragmentos de código demasiado complicados.
¿Alguna sugerencia? ¿Debo escribir una función para esto o hay una solución simple?
dropna=False
engroupby()
conseguir el resultado deseado. Más informaciónRespuestas:
Esto se menciona en la sección Datos faltantes de los documentos :
Una solución alternativa es usar un marcador de posición antes de hacer el grupo (p. Ej. -1):
Dicho esto, esto parece un truco bastante horrible ... tal vez debería haber una opción para incluir NaN en groupby (vea este tema de github , que utiliza el mismo truco de marcador de posición).
fuente
Tema antiguo, si alguien todavía tropieza con esto, otra solución es convertir a través de .astype (str) a cadena antes de agrupar. Eso conservará los NaN's.
fuente
sum
dea
es la concatenación de cadenas aquí, no una suma numérica. Esto solo "funciona" porque 'b' consistía en entradas distintas. Necesitas 'a' para ser numérico y 'b' para ser cadenapandas> = 1.1
Desde pandas 1.1 tiene un mejor control sobre este comportamiento, los valores de NA ahora están permitidos en el mero usando
dropna=False
:fuente
No puedo agregar un comentario a M. Kiewisch ya que no tengo suficientes puntos de reputación (solo tengo 41 pero necesito más de 50 para comentar).
De todos modos, solo quiero señalar que la solución de M. Kiewisch no funciona como es y puede necesitar más ajustes. Considere por ejemplo
lo que muestra que para el grupo b = 4.0, el valor correspondiente es 15 en lugar de 6. Aquí solo se concatena 1 y 5 como cadenas en lugar de agregarlo como números.
fuente
b
columnaUn pequeño punto a la solución de Andy Hayden: no funciona (¿ya?) Porque
np.nan == np.nan
cedeFalse
, por lo que lareplace
función en realidad no hace nada.Lo que funcionó para mí fue esto:
(Al menos ese es el comportamiento de Pandas 0.19.2. Lamento agregarlo como una respuesta diferente, no tengo suficiente reputación para comentar).
fuente
df['b'].fillna(-1)
.Todas las respuestas proporcionadas hasta ahora dan como resultado un comportamiento potencialmente peligroso, ya que es muy posible que seleccione un valor ficticio que realmente sea parte del conjunto de datos. Esto es cada vez más probable a medida que crea grupos con muchos atributos. En pocas palabras, el enfoque no siempre se generaliza bien.
Una solución menos hacky es usar pd.drop_duplicates () para crear un índice único de combinaciones de valores, cada una con su propia ID, y luego agruparlas en esa identificación. Es más detallado pero hace el trabajo:
Tenga en cuenta que ahora simplemente puede hacer lo siguiente:
Esto devolverá el resultado exitoso sin tener que preocuparse por sobrescribir datos reales que se confunden con un valor ficticio.
fuente
Ya respondí esto, pero por alguna razón la respuesta se convirtió en un comentario. Sin embargo, esta es la solución más eficiente:
No poder incluir (y propagar) NaNs en grupos es bastante agravante. Citar a R no es convincente, ya que este comportamiento no es consistente con muchas otras cosas. De todos modos, el truco ficticio también es bastante malo. Sin embargo, el tamaño (incluye NaNs) y el recuento (ignora los NaNs) de un grupo serán diferentes si hay NaNs.
Cuando estos difieren, puede volver a establecer el valor en Ninguno para el resultado de la función de agregación para ese grupo.
fuente
Pandas 1.1 instalado en Anaconda
No puedo comentar la respuesta de cs95 pero él me ayudó a resolver el problema.
Traté de instalar Pandas 1.1 pero falló usando su código, así que busqué en Google y pude instalar.
Primero ejecuto anaconda prompt como administrador y pego el siguiente código:
pip install pandas==1.1.0rc0
Después de eso incluye el uso
dropna = False
Enlace: https://libraries.io/pypi/pandas
fuente
df = df.fillna("")
esto funcionó para mífuente