Python Pandas - Datos faltantes

La falta de datos siempre es un problema en escenarios de la vida real. Áreas como el aprendizaje automático y la minería de datos enfrentan problemas graves en la precisión de las predicciones de sus modelos debido a la mala calidad de los datos causada por valores perdidos. En estas áreas, el tratamiento de los valores perdidos es un punto importante de enfoque para hacer que sus modelos sean más precisos y válidos.

¿Cuándo y por qué se pierden los datos?

Consideremos una encuesta en línea para un producto. Muchas veces, las personas no comparten toda la información relacionada con ellos. Pocas personas comparten su experiencia, pero no cuánto tiempo están usando el producto; pocas personas comparten cuánto tiempo están usando el producto, su experiencia pero no su información de contacto. Así, de una u otra forma siempre falta una parte de los datos, y esto es muy común en tiempo real.

Veamos ahora cómo podemos manejar los valores perdidos (digamos NA o NaN) usando Pandas.

# import the pandas library
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f',
'h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print df

Sus output es como sigue -

one        two      three
a   0.077988   0.476149   0.965836
b        NaN        NaN        NaN
c  -0.390208  -0.551605  -2.301950
d        NaN        NaN        NaN
e  -2.000303  -0.788201   1.510072
f  -0.930230  -0.670473   1.146615
g        NaN        NaN        NaN
h   0.085100   0.532791   0.887415

Usando la reindexación, hemos creado un DataFrame con valores faltantes. En la salida,NaN medio Not a Number.

Verificar valores perdidos

Para facilitar la detección de valores perdidos (y en diferentes tipos de matriz), Pandas proporciona la isnull() y notnull() funciones, que también son métodos en objetos Series y DataFrame -

Ejemplo 1

import pandas as pd
import numpy as np
 
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f',
'h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print df['one'].isnull()

Sus output es como sigue -

a  False
b  True
c  False
d  True
e  False
f  False
g  True
h  False
Name: one, dtype: bool

Ejemplo 2

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f',
'h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print df['one'].notnull()

Sus output es como sigue -

a  True
b  False
c  True
d  False
e  True
f  True
g  False
h  True
Name: one, dtype: bool

Cálculos con datos faltantes

  • Al sumar datos, NA se tratará como cero
  • Si todos los datos son NA, el resultado será NA

Ejemplo 1

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f',
'h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print df['one'].sum()

Sus output es como sigue -

2.02357685917

Ejemplo 2

import pandas as pd
import numpy as np

df = pd.DataFrame(index=[0,1,2,3,4,5],columns=['one','two'])
print df['one'].sum()

Sus output es como sigue -

nan

Limpieza / llenado de datos faltantes

Pandas proporciona varios métodos para limpiar los valores faltantes. La función fillna puede “completar” los valores NA con datos no nulos de un par de formas, que hemos ilustrado en las siguientes secciones.

Reemplazar NaN con un valor escalar

El siguiente programa muestra cómo se puede reemplazar "NaN" por "0".

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(3, 3), index=['a', 'c', 'e'],columns=['one',
'two', 'three'])

df = df.reindex(['a', 'b', 'c'])

print df
print ("NaN replaced with '0':")
print df.fillna(0)

Sus output es como sigue -

one        two     three
a  -0.576991  -0.741695  0.553172
b        NaN        NaN       NaN
c   0.744328  -1.735166  1.749580

NaN replaced with '0':
         one        two     three
a  -0.576991  -0.741695  0.553172
b   0.000000   0.000000  0.000000
c   0.744328  -1.735166  1.749580

Aquí, estamos llenando con valor cero; en su lugar, también podemos completar con cualquier otro valor.

Rellenar NA hacia adelante y hacia atrás

Usando los conceptos de relleno discutidos en el Capítulo de ReIndexación, completaremos los valores faltantes.

No Señor Método y acción
1

pad/fill

Métodos de relleno Adelante

2

bfill/backfill

Rellenar métodos al revés

Ejemplo 1

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f',
'h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print df.fillna(method='pad')

Sus output es como sigue -

one        two      three
a   0.077988   0.476149   0.965836
b   0.077988   0.476149   0.965836
c  -0.390208  -0.551605  -2.301950
d  -0.390208  -0.551605  -2.301950
e  -2.000303  -0.788201   1.510072
f  -0.930230  -0.670473   1.146615
g  -0.930230  -0.670473   1.146615
h   0.085100   0.532791   0.887415

Ejemplo 2

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f',
'h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print df.fillna(method='backfill')

Sus output es como sigue -

one        two      three
a   0.077988   0.476149   0.965836
b  -0.390208  -0.551605  -2.301950
c  -0.390208  -0.551605  -2.301950
d  -2.000303  -0.788201   1.510072
e  -2.000303  -0.788201   1.510072
f  -0.930230  -0.670473   1.146615
g   0.085100   0.532791   0.887415
h   0.085100   0.532791   0.887415

Eliminar valores perdidos

Si simplemente desea excluir los valores faltantes, utilice la dropna función junto con el axisargumento. Por defecto, eje = 0, es decir, a lo largo de la fila, lo que significa que si cualquier valor dentro de una fila es NA, se excluye toda la fila.

Ejemplo 1

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f',
'h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
print df.dropna()

Sus output es como sigue -

one        two      three
a   0.077988   0.476149   0.965836
c  -0.390208  -0.551605  -2.301950
e  -2.000303  -0.788201   1.510072
f  -0.930230  -0.670473   1.146615
h   0.085100   0.532791   0.887415

Ejemplo 2

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f',
'h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
print df.dropna(axis=1)

Sus output es como sigue -

Empty DataFrame
Columns: [ ]
Index: [a, b, c, d, e, f, g, h]

Reemplazar valores faltantes (o) genéricos

Muchas veces, tenemos que reemplazar un valor genérico con algún valor específico. Podemos lograr esto aplicando el método de reemplazo.

Reemplazar NA con un valor escalar es un comportamiento equivalente del fillna() función.

Ejemplo 1

import pandas as pd
import numpy as np

df = pd.DataFrame({'one':[10,20,30,40,50,2000], 'two':[1000,0,30,40,50,60]})

print df.replace({1000:10,2000:60})

Sus output es como sigue -

one  two
0   10   10
1   20    0
2   30   30
3   40   40
4   50   50
5   60   60

Ejemplo 2

import pandas as pd
import numpy as np

df = pd.DataFrame({'one':[10,20,30,40,50,2000], 'two':[1000,0,30,40,50,60]})
print df.replace({1000:10,2000:60})

Sus output es como sigue -

one  two
0   10   10
1   20    0
2   30   30
3   40   40
4   50   50
5   60   60