Para promediar ignorando los NaN, usa np.nanmean(arreglo) en NumPy o serie.mean() en pandas, que los omite por omisión (skipna=True). En Python puro, filtra antes: [x for x in datos if not math.isnan(x)]. Un solo NaN contamina cualquier suma, así que np.mean y statistics.mean devuelven nan si no lo quitas.
Qué hace cada herramienta con un valor faltante
| Herramienta | Con NaN | Con None |
|---|---|---|
sum(x) / len(x) | Devuelve nan | TypeError |
statistics.mean | Devuelve nan | TypeError |
np.mean | Devuelve nan | TypeError (arreglo de tipo object) |
np.nanmean | Lo ignora | Conviértelo antes a np.nan |
serie.mean() en pandas | Lo ignora | Lo ignora (pandas lo guarda como NaN) |
serie.mean(skipna=False) | Devuelve nan | Devuelve nan |
Paso a paso
- Averigua cómo vienen marcados los faltantes:
NaN,None, celdas vacías,"n/d"o-999. - Conviértelos todos a
NaN(en pandas, conpd.to_numeric(..., errors="coerce")oreplace). - Decide si un faltante debe ignorarse o contar como 0. No es lo mismo un sensor apagado que una tarea no entregada.
- Usa la función que omite
NaNy anota cuántos datos quedaron: el divisor cambia.
Ejemplos resueltos
Ejemplo 1: lecturas de un sensor con huecos
import numpy as np
lect = np.array([18.2, np.nan, 21.5, 19.9, np.nan, 20.4])
print(np.mean(lect))
print(np.nanmean(lect))
print(np.count_nonzero(~np.isnan(lect)))
nan
20.0
4
np.nanmean suma los 4 valores válidos (80.0) y divide entre 4, no entre 6. La tercera línea cuenta cuántos datos entraron al promedio, algo que conviene reportar junto al resultado. En matrices, np.nanmean(m, axis=0) hace lo mismo por columna.
Ejemplo 2: pandas y la diferencia entre ignorar y rellenar con cero
import pandas as pd
s = pd.Series([18.2, None, 21.5, 19.9, None, 20.4])
print(s.mean())
print(s.mean(skipna=False))
print(s.fillna(0).mean())
print(s.count(), len(s))
20.0
nan
13.333333333333334
4 6
fillna(0) cambia la pregunta: ya no es la temperatura promedio de las lecturas válidas, sino un promedio en el que dos lecturas valen 0 °C. El resultado baja a 13.33, que no describe nada real. count() da los valores no nulos; len(), el total de filas.
Ejemplo 3: columna con textos como «n/d» y celdas vacías
Al leer un CSV, una columna con un solo texto se carga como texto y mean() falla. Conviértela forzando los valores no numéricos a NaN:
t = pd.Series(["8", "9.5", "", "n/d", "7"])
nums = pd.to_numeric(t, errors="coerce")
print(nums.tolist())
print(nums.mean())
[8.0, 9.5, nan, nan, 7.0]
8.166666666666666
Con errors="coerce", todo lo que no se puede leer como número se vuelve NaN y después se ignora. Revisa cuántos valores se perdieron (nums.isna().sum()) para no descartar datos válidos mal escritos, como "8,5" con coma decimal: conviértelos antes con t.str.replace(",", ".").
En Python puro
import math, statistics as st
datos = [8.0, float("nan"), 9.5, 7.0]
print(st.mean(datos))
print(st.mean([x for x in datos if not math.isnan(x)]))
nan
8.166666666666666
Si los faltantes son None, filtra con x is not None. Si puede haber de los dos tipos, x is not None and x == x descarta ambos, porque NaN nunca es igual a sí mismo.
Errores comunes
RuntimeWarning: Mean of empty slicey resultadonan. Todos los valores eranNaN;np.nanmeanno tiene nada que promediar.- Rellenar con 0 por costumbre. Solo es correcto si el faltante realmente vale cero. Si no, sesga el promedio hacia abajo.
- Comparar con
x == np.nan. Siempre esFalse. Usanp.isnan(x),math.isnan(x)opd.isna(x). - No reportar el tamaño de la muestra. Un promedio de 4 lecturas de 6 posibles debe decir que faltan 2.
- Valores centinela como
-999. No sonNaNy entran al promedio. Reemplázalos cons.replace(-999, np.nan).
En Excel, PROMEDIO ya ignora las celdas vacías; lo que no ignora son los ceros, y para eso se usa el criterio "<>0" de PROMEDIO.SI en Excel.
Fuentes
- NumPy, numpy.nanmean. Comportamiento con NaN y advertencia con todos NaN. Consultado el 11 de noviembre de 2026.
- pandas, DataFrame.mean. Parámetros skipna y numeric_only. Consultado el 11 de noviembre de 2026.