python - read - Reemplazar valores en blanco(espacio en blanco) con NaN en pandas
python pandas excel (8)
Quiero encontrar todos los valores en un marco de datos de Pandas que contengan espacios en blanco (cualquier cantidad arbitraria) y reemplazar esos valores con NaN.
¿Alguna idea de cómo se puede mejorar esto?
Básicamente quiero convertir esto:
A B C
2000-01-01 -0.532681 foo 0
2000-01-02 1.490752 bar 1
2000-01-03 -1.387326 foo 2
2000-01-04 0.814772 baz
2000-01-05 -0.222552 4
2000-01-06 -1.176781 qux
Dentro de esto:
A B C
2000-01-01 -0.532681 foo 0
2000-01-02 1.490752 bar 1
2000-01-03 -1.387326 foo 2
2000-01-04 0.814772 baz NaN
2000-01-05 -0.222552 NaN 4
2000-01-06 -1.176781 qux NaN
He logrado hacerlo con el siguiente código, pero es feo. No es Pythonic y estoy seguro de que tampoco es el uso más eficiente de los pandas. Me desplazo por cada columna y hago un reemplazo booleano contra una máscara de columna generada al aplicar una función que realiza una búsqueda de expresiones regulares de cada valor, haciendo coincidir en espacios en blanco.
for i in df.columns:
df[i][df[i].apply(lambda i: True if re.search(''^/s*$'', str(i)) else False)]=None
Podría optimizarse un poco al solo iterar a través de campos que podrían contener cadenas vacías:
if df[i].dtype == np.dtype(''object'')
Pero eso no es una gran mejora
Y, por último, este código establece las cadenas de destino a Ninguno, que funciona con las funciones de Pandas como fillna (), pero sería bueno para completar si pudiera insertar un NaN directamente en lugar de None.
¡Ayuda!
Creo que df.replace()
hace el trabajo:
df = pd.DataFrame([
[-0.532681, ''foo'', 0],
[1.490752, ''bar'', 1],
[-1.387326, ''foo'', 2],
[0.814772, ''baz'', '' ''],
[-0.222552, '' '', 4],
[-1.176781, ''qux'', '' ''],
], columns=''A B C''.split(), index=pd.date_range(''2000-01-01'',''2000-01-06''))
print df.replace(r''/s+'', np.nan, regex=True)
Produce:
A B C
2000-01-01 -0.532681 foo 0
2000-01-02 1.490752 bar 1
2000-01-03 -1.387326 foo 2
2000-01-04 0.814772 baz NaN
2000-01-05 -0.222552 NaN 4
2000-01-06 -1.176781 qux NaN
Haré esto:
df = df.apply(lambda x: x.str.strip()).replace('''', np.nan)
o
df = df.apply(lambda x: x.str.strip() if isinstance(x, str) else x).replace('''', np.nan)
Puedes quitar todo str, luego reemplazar str vacío con np.nan
.
Para una solución muy rápida y sencilla en la que compara la igualdad con un valor único, puede usar el método de mask
.
df.mask(df == '' '')
Qué tal si:
d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)
La función de applymap
aplicación aplica una función a cada celda del marco de datos.
Si está exportando los datos del archivo CSV, puede ser tan simple como esto:
df = pd.read_csv(file_csv, na_values='' '')
Esto creará el marco de datos y reemplazará los valores en blanco como Na
Si solo quiere reemplazar cadena vacía y registros con solo espacios, ¡la respuesta correcta es !
df = df.replace(r''^/s*$'', np.nan, regex=True)
La respuesta aceptada
df.replace(r''/s+'', np.nan, regex=True)
¡No reemplaza una cadena vacía! Puede probarse con el ejemplo dado ligeramente actualizado:
df = pd.DataFrame([
[-0.532681, ''foo'', 0],
[1.490752, ''bar'', 1],
[-1.387326, ''fo o'', 2],
[0.814772, ''baz'', '' ''],
[-0.222552, '' '', 4],
[-1.176781, ''qux'', ''''],
], columns=''A B C''.split(), index=pd.date_range(''2000-01-01'',''2000-01-06''))
Tenga en cuenta, también, que ''fo o'' no se reemplaza con Nan, aunque contiene un espacio. Además, tenga en cuenta que un simple:
df.replace(r'''', np.NaN)
Tampoco funciona, pruébalo.
también puedes usar un filtro para hacerlo.
df = PD.DataFrame([
[-0.532681, ''foo'', 0],
[1.490752, ''bar'', 1],
[-1.387326, ''foo'', 2],
[0.814772, ''baz'', '' ''],
[-0.222552, '' '', 4],
[-1.176781, ''qux'', '' ''])
df[df=='''']=''nan''
df=df.astype(float)
La más simple de todas las soluciones:
df = df.replace(r''^/s+$'', np.nan, regex=True)