Antes de continuar con esta publicación, es importante comprender la diferencia entre NaN y None . Uno es un tipo flotante, el otro es un tipo de objeto. Pandas es más adecuado para trabajar con tipos escalares, ya que se pueden vectorizar muchos métodos en estos tipos. Pandas intenta manejar None y NaN de manera consistente, pero NumPy no puede.
Mi sugerencia ( y la de Andy ) es seguir con NaN.
Pero para responder a tu pregunta ...
pandas> = 0.18: Use na_values=['-']
argumento conread_csv
Si cargó estos datos desde CSV / Excel, tengo buenas noticias para usted. Puede anular esto en la raíz durante la carga de datos en lugar de tener que escribir una solución con código como paso posterior.
La mayoría de las pd.read_*
funciones (como read_csv
y read_excel
) aceptan un na_values
atributo.
file.csv
A,B
-,1
3,-
2,-
5,3
1,-2
-5,4
-1,-1
-,0
9,0
Ahora, para convertir los -
caracteres en NaN, haga,
import pandas as pd
df = pd.read_csv('file.csv', na_values=['-'])
df
A B
0 NaN 1.0
1 3.0 NaN
2 2.0 NaN
3 5.0 3.0
4 1.0 -2.0
5 -5.0 4.0
6 -1.0 -1.0
7 NaN 0.0
8 9.0 0.0
Y similar para otras funciones / formatos de archivo.
PD: en v0.24 +, puede conservar el tipo de entero incluso si su columna tiene NaN (sí, hable de tener el pastel y comérselo también). Puede especificardtype='Int32'
df = pd.read_csv('file.csv', na_values=['-'], dtype='Int32')
df
A B
0 NaN 1
1 3 NaN
2 2 NaN
3 5 3
4 1 -2
5 -5 4
6 -1 -1
7 NaN 0
8 9 0
df.dtypes
A Int32
B Int32
dtype: object
El dtype no es un tipo int convencional ... sino más bien, un tipo entero que acepta valores NULL. Hay otras opciones.
Manejo de datos numéricos: pd.to_numeric
conerrors='coerce
Si está tratando con datos numéricos, una solución más rápida es usar pd.to_numeric
con el errors='coerce'
argumento, que coacciona valores no válidos (valores que no se pueden convertir en numéricos) a NaN.
pd.to_numeric(df['A'], errors='coerce')
0 NaN
1 3.0
2 2.0
3 5.0
4 1.0
5 -5.0
6 -1.0
7 NaN
8 9.0
Name: A, dtype: float64
Para retener (nullable) dtype entero, use
pd.to_numeric(df['A'], errors='coerce').astype('Int32')
0 NaN
1 3
2 2
3 5
4 1
5 -5
6 -1
7 NaN
8 9
Name: A, dtype: Int32
Para coaccionar varias columnas, use apply
:
df[['A', 'B']].apply(pd.to_numeric, errors='coerce').astype('Int32')
A B
0 NaN 1
1 3 NaN
2 2 NaN
3 5 3
4 1 -2
5 -5 4
6 -1 -1
7 NaN 0
8 9 0
... y asigne el resultado de nuevo después.
Puede encontrar más información en esta respuesta .
write_frame
No analizaNaN
s anone
s?