Solución:
Pandas reconocerá un valor como nulo si es un np.nan
objeto, que se imprimirá como NaN
en el DataFrame. Los valores que faltan son probablemente cadenas vacías, que Pandas no reconoce como nulos. Para solucionar esto, puede convertir las picaduras vacías (o lo que sea que esté en sus celdas vacías) a np.nan
objetos usando replace()
y luego llamar dropna()
en su DataFrame para eliminar filas con inquilinos nulos.
Para demostrarlo, creamos un DataFrame con algunos valores aleatorios y algunas cadenas vacías en un Tenants
columna:
>>> import pandas as pd
>>> import numpy as np
>>>
>>> df = pd.DataFrame(np.random.randn(10, 2), columns=list('AB'))
>>> df['Tenant'] = np.random.choice(['Babar', 'Rataxes', ''], 10)
>>> print df
A B Tenant
0 -0.588412 -1.179306 Babar
1 -0.008562 0.725239
2 0.282146 0.421721 Rataxes
3 0.627611 -0.661126 Babar
4 0.805304 -0.834214
5 -0.514568 1.890647 Babar
6 -1.188436 0.294792 Rataxes
7 1.471766 -0.267807 Babar
8 -1.730745 1.358165 Rataxes
9 0.066946 0.375640
Ahora reemplazamos las cadenas vacías en el Tenants
columna con np.nan
objetos, así:
>>> df['Tenant'].replace('', np.nan, inplace=True)
>>> print df
A B Tenant
0 -0.588412 -1.179306 Babar
1 -0.008562 0.725239 NaN
2 0.282146 0.421721 Rataxes
3 0.627611 -0.661126 Babar
4 0.805304 -0.834214 NaN
5 -0.514568 1.890647 Babar
6 -1.188436 0.294792 Rataxes
7 1.471766 -0.267807 Babar
8 -1.730745 1.358165 Rataxes
9 0.066946 0.375640 NaN
Ahora podemos eliminar los valores nulos:
>>> df.dropna(subset=['Tenant'], inplace=True)
>>> print df
A B Tenant
0 -0.588412 -1.179306 Babar
2 0.282146 0.421721 Rataxes
3 0.627611 -0.661126 Babar
5 -0.514568 1.890647 Babar
6 -1.188436 0.294792 Rataxes
7 1.471766 -0.267807 Babar
8 -1.730745 1.358165 Rataxes
Pythonic + Pandorable: df[df['col'].astype(bool)]
Las cadenas vacías son falsas, lo que significa que puede filtrar por valores bool como este:
df = pd.DataFrame({
'A': range(5),
'B': ['foo', '', 'bar', '', 'xyz']
})
df
A B
0 0 foo
1 1
2 2 bar
3 3
4 4 xyz
df['B'].astype(bool)
0 True
1 False
2 True
3 False
4 True
Name: B, dtype: bool
df[df['B'].astype(bool)]
A B
0 0 foo
2 2 bar
4 4 xyz
Si su objetivo es eliminar no solo cadenas vacías, sino también cadenas que solo contienen espacios en blanco, use str.strip
antemano:
df[df['B'].str.strip().astype(bool)]
A B
0 0 foo
2 2 bar
4 4 xyz
Más rápido de lo que piensas
.astype
es una operación vectorizada, esto es más rápido que todas las opciones presentadas hasta ahora. Al menos, de mis pruebas. YMMV.
Aquí hay una comparación de tiempos, he incluido algunos otros métodos que se me ocurren.
Código de evaluación comparativa, como referencia:
import pandas as pd
import perfplot
df1 = pd.DataFrame({
'A': range(5),
'B': ['foo', '', 'bar', '', 'xyz']
})
perfplot.show(
setup=lambda n: pd.concat([df1] * n, ignore_index=True),
kernels=[
lambda df: df[df['B'].astype(bool)],
lambda df: df[df['B'] != ''],
lambda df: df[df['B'].replace('', np.nan).notna()], # optimized 1-col
lambda df: df.replace({'B': {'': np.nan}}).dropna(subset=['B']),
],
labels=['astype', "!= ''", "replace + notna", "replace + dropna", ],
n_range=[2**k for k in range(1, 15)],
xlabel="N",
logx=True,
logy=True,
equality_check=pd.DataFrame.equals)
value_counts omite NaN de forma predeterminada, por lo que lo más probable es que se trate de “”.
Así que puedes filtrarlos como
filter = df["Tenant"] != ""
dfNew = df[filter]