unstack sort column pandas grouping nan

pandas - sort - columnas groupby con valores NaN(faltantes)



pandas stack (6)

Aunque por defecto no hay una función de skipna en las agregaciones de grupos, hay una manera fácil y limpia de hacerlo:

def custom_mean(df): return df.mean(skipna=False) group.agg({"your_col_name_to_be_aggregated":custom_mean})

¡Eso es!

Tenga en cuenta que no he comparado esto, pero espero que sea más rápido de lo que se discutió en las respuestas anteriores.

Respuesta encontrada en el doc .

Tengo un DataFrame con muchos valores perdidos en las 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 dejado caer las filas con los valores objetivo de NaN. (¡Quiero incluir estas filas!)

Como necesito muchas de estas operaciones (muchos cols tienen valores perdidos) y uso funciones más complicadas que solo medianas (típicamente 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?


Esto se menciona en la sección Datos perdidos de los documentos :

Los grupos de NA en GroupBy se excluyen automáticamente. Este comportamiento es consistente con R, por ejemplo.

Una solución es usar un marcador de posición antes de hacer el grupo por (ej. -1):

In [11]: df.fillna(-1) Out[11]: a b 0 1 4 1 2 -1 2 3 6 In [12]: df.fillna(-1).groupby(''b'').sum() Out[12]: a b -1 2 4 1 6 3

Dicho esto, esto parece un hack bastante horrible ... tal vez debería haber una opción para incluir NaN en groupby (mira este problema de github , que usa el mismo hack de marcador de posición).


No puedo agregar un comentario a M. Kiewisch porque 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 está y puede necesitar más ajustes. Considera por ejemplo

>>> df = pd.DataFrame({''a'': [1, 2, 3, 5], ''b'': [4, np.NaN, 6, 4]}) >>> df a b 0 1 4.0 1 2 NaN 2 3 6.0 3 5 4.0 >>> df.groupby([''b'']).sum() a b 4.0 6 6.0 3 >>> df.astype(str).groupby([''b'']).sum() a b 4.0 15 6.0 3 nan 2

que muestra que para el grupo b = 4.0, el valor correspondiente es 15 en lugar de 6. Aquí simplemente concatena 1 y 5 como cadenas en lugar de agregarlo como números.


Tema antiguo, si alguien aún se tropieza con esto, otra solución es convertir mediante .astype (str) en una cadena antes de agrupar. Eso conservará los NaN.

in:

df = pd.DataFrame({''a'': [''1'', ''2'', ''3''], ''b'': [''4'', np.NaN, ''6'']}) df.astype(str).groupby([''b'']).sum()

out: a b 4 1 6 3 nan 2


Un pequeño punto a la solución de Andy Hayden: no funciona (¿ya?) Porque np.nan == np.nan produce False , por lo que la función de replace realidad no hace nada.

Lo que funcionó para mí fue esto:

df[''b''] = df[''b''].apply(lambda x: x if not np.isnan(x) else -1)

(Al menos ese es el comportamiento de Pandas 0.19.2. Lamento agregarlo como una respuesta diferente, no tengo suficiente reputación para comentar).


Ya respondí esto, pero alguna razón por la que 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 irritante. Citar R no es convincente, ya que este comportamiento no es coherente con muchas otras cosas. De todos modos, el truco truco también es bastante malo. Sin embargo, el tamaño (incluye NaN) y el recuento (ignora los NaN) de un grupo serán diferentes si hay NaN.

dfgrouped = df.groupby([''b'']).a.agg([''sum'',''size'',''count'']) dfgrouped[''sum''][dfgrouped[''size'']!=dfgrouped[''count'']] = None

Cuando estos difieren, puede establecer el valor nuevamente en Ninguno para el resultado de la función de agregación para ese grupo.