Cómo configurar una celda en NaN en un marco de datos de pandas

97

Me gustaría reemplazar los valores incorrectos en una columna de un marco de datos por NaN.

mydata = {'x' : [10, 50, 18, 32, 47, 20], 'y' : ['12', '11', 'N/A', '13', '15', 'N/A']}
df = pd.DataFrame(mydata)

df[df.y == 'N/A']['y'] = np.nan

Sin embargo, la última línea falla y arroja una advertencia porque está trabajando en una copia de df. Entonces, ¿cuál es la forma correcta de manejar esto? He visto muchas soluciones con iloc o ix pero aquí, necesito usar una condición booleana.

Mark Morrisson
fuente

Respuestas:

122

solo usa replace:

In [106]:
df.replace('N/A',np.NaN)

Out[106]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN

Lo que está intentando se llama indexación en cadena: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

Puede utilizar locpara asegurarse de operar en el dF original:

In [108]:
df.loc[df['y'] == 'N/A','y'] = np.nan
df

Out[108]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN
EdChum
fuente
13

Si bien el uso replaceparece resolver el problema, me gustaría proponer una alternativa. Problema con la combinación de valores numéricos y algunos valores de cadena en la columna para no tener cadenas reemplazadas con np.nan, sino para hacer que toda la columna sea correcta. Apostaría a que la columna original probablemente sea de un tipo de objeto

Name: y, dtype: object

Lo que realmente necesita es convertirla en una columna numérica (tendrá el tipo adecuado y sería bastante más rápida), con todos los valores no numéricos reemplazados por NaN.

Por lo tanto, un buen código de conversión sería

pd.to_numeric(df['y'], errors='coerce')

Especifique errors='coerce'para forzar cadenas que no se pueden analizar a un valor numérico para convertirse en NaN. El tipo de columna sería

Name: y, dtype: float64
Severin Pappadeux
fuente
10

Puede usar reemplazar:

df['y'] = df['y'].replace({'N/A': np.nan})

También tenga en cuenta el inplaceparámetro para replace. Puedes hacer algo como:

df.replace({'N/A': np.nan}, inplace=True)

Esto reemplazará todas las instancias en el df sin crear una copia.

Del mismo modo, si se encuentra con otros tipos de valores desconocidos, como una cadena vacía o un valor Ninguno:

df['y'] = df['y'].replace({'': np.nan})

df['y'] = df['y'].replace({None: np.nan})

Referencia: Pandas Latest - Reemplazar

jmorrison
fuente
1
df.loc[df.y == 'N/A',['y']] = np.nan

Esto soluciona tu problema. Con el doble [], está trabajando en una copia del DataFrame. Tienes que especificar la ubicación exacta en una llamada para poder modificarla.

jeremie benichou
fuente
0

Puede probar estos fragmentos.

En [16]: mydata = {'x': [10, 50, 18, 32, 47, 20], 'y': ['12', '11', 'N / A', '13', ' 15 ',' N / A ']}
En [17]: df = pd.DataFrame (mydata)

En [18]: df.y [df.y == "N / A"] = np.nan

Fuera [19]: df 
    xy
0 10 12
1 50 11
2 18 NaN
3 32 13
4 47 15
5 20 NaN
rolandpeng
fuente
0

A partir de pandas 1.0.0, ya no necesita usar numpy para crear valores nulos en su marco de datos. En su lugar, puede usar pandas.NA (que es de tipo pandas._libs.missing.NAType), por lo que se tratará como nulo dentro del marco de datos, pero no será nulo fuera del contexto del marco de datos.

slevin886
fuente