Solución:
Para responder directamente al título original de esta pregunta “Cómo eliminar filas de un DataFrame de pandas basado en una expresión condicional” (que entiendo que no es necesariamente el problema del OP, pero podría ayudar a otros usuarios a encontrar esta pregunta) una forma de hacerlo es usar el método de la gota:
df = df.drop(some labels)
df = df.drop(df[<some boolean condition>].index)
Ejemplo
Para eliminar todas las filas donde la columna ‘puntuación’ es <50:
df = df.drop(df[df.score < 50].index)
Versión en el lugar (como se señaló en los comentarios)
df.drop(df[df.score < 50].index, inplace=True)
Varias condiciones
(ver Indexación booleana)
Los operadores son:
|
poror
,&
porand
, y~
pornot
. Estos deben agruparse mediante paréntesis.
Para eliminar todas las filas donde la columna ‘puntuación’ es <50 y> 20
df = df.drop(df[(df.score < 50) & (df.score > 20)].index)
Cuando tu lo hagas len(df['column name'])
solo obtiene un número, a saber, el número de filas en el DataFrame (es decir, la longitud de la columna en sí). Si quieres postularte len
para cada elemento de la columna, utilice df['column name'].map(len)
. Así que intenta
df[df['column name'].map(len) < 2]
Puede asignar el DataFrame
a una versión filtrada de sí mismo:
df = df[df.score > 50]
Esto es mas rapido que drop
:
%%timeit
test = pd.DataFrame({'x': np.random.randn(int(1e6))})
test = test[test.x < 0]
# 54.5 ms ± 2.02 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
test = pd.DataFrame({'x': np.random.randn(int(1e6))})
test.drop(test[test.x > 0].index, inplace=True)
# 201 ms ± 17.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
test = pd.DataFrame({'x': np.random.randn(int(1e6))})
test = test.drop(test[test.x > 0].index)
# 194 ms ± 7.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)