Eliminar la fila del marco de datos en pandas según el valor de la columna

512

Tengo el siguiente DataFrame:

             daysago  line_race rating        rw    wrating
 line_date                                                 
 2007-03-31       62         11     56  1.000000  56.000000
 2007-03-10       83         11     67  1.000000  67.000000
 2007-02-10      111          9     66  1.000000  66.000000
 2007-01-13      139         10     83  0.880678  73.096278
 2006-12-23      160         10     88  0.793033  69.786942
 2006-11-09      204          9     52  0.636655  33.106077
 2006-10-22      222          8     66  0.581946  38.408408
 2006-09-29      245          9     70  0.518825  36.317752
 2006-09-16      258         11     68  0.486226  33.063381
 2006-08-30      275          8     72  0.446667  32.160051
 2006-02-11      475          5     65  0.164591  10.698423
 2006-01-13      504          0     70  0.142409   9.968634
 2006-01-02      515          0     64  0.134800   8.627219
 2005-12-06      542          0     70  0.117803   8.246238
 2005-11-29      549          0     70  0.113758   7.963072
 2005-11-22      556          0     -1  0.109852  -0.109852
 2005-11-01      577          0     -1  0.098919  -0.098919
 2005-10-20      589          0     -1  0.093168  -0.093168
 2005-09-27      612          0     -1  0.083063  -0.083063
 2005-09-07      632          0     -1  0.075171  -0.075171
 2005-06-12      719          0     69  0.048690   3.359623
 2005-05-29      733          0     -1  0.045404  -0.045404
 2005-05-02      760          0     -1  0.039679  -0.039679
 2005-04-02      790          0     -1  0.034160  -0.034160
 2005-03-13      810          0     -1  0.030915  -0.030915
 2004-11-09      934          0     -1  0.016647  -0.016647

Necesito eliminar las filas donde line_racees igual a 0. ¿Cuál es la forma más eficiente de hacer esto?

TravisVOX
fuente

Respuestas:

879

Si lo entiendo correctamente, debería ser tan simple como:

df = df[df.line_race != 0]
tshauck
fuente
16
¿Costará esto más memoria si dfes grande? ¿O puedo hacerlo en el lugar?
ziyuang
10
Simplemente lo ejecuté en una dffila de 2M y fue bastante rápido.
Dror
46
@vfxGer si hay un espacio en la columna, como 'carrera de línea', entonces puedes hacerlodf = df[df['line race'] != 0]
Paul
3
¿Cómo modificaríamos este comando si quisiéramos eliminar toda la fila si el valor en cuestión se encuentra en alguna de las columnas de esa fila?
Alex
3
¡Gracias! Fwiw, para mí esto tenía que serdf=df[~df['DATE'].isin(['2015-10-30.1', '2015-11-30.1', '2015-12-31.1'])]
citynorman
182

Pero para cualquier bypass futuro, podría mencionar que df = df[df.line_race != 0]no hace nada al intentar filtrar Nonevalores faltantes.

Funciona:

df = df[df.line_race != 0]

No hace nada:

df = df[df.line_race != None]

Funciona:

df = df[df.line_race.notnull()]
wonderkid2
fuente
44
¿Cómo hacer eso si no sabemos el nombre de la columna?
Piyush S. Wanare
Podría hacerlo df = df[df.columns[2].notnull()], pero de una forma u otra necesita poder indexar la columna de alguna manera.
erekalper
1
df = df[df.line_race != 0]elimina las filas pero tampoco restablece el índice. Entonces, cuando agrega otra fila en el df, es posible que no se agregue al final. Me gustaría recomendar el restablecimiento del índice después de que la operación ( df = df.reset_index(drop=True))
the_new_james
Nunca debe comparar a Ninguno con el ==operador para comenzar. stackoverflow.com/questions/3257919/…
Bram Vanroy
40

La mejor manera de hacerlo es con el enmascaramiento booleano:

In [56]: df
Out[56]:
     line_date  daysago  line_race  rating    raw  wrating
0   2007-03-31       62         11      56  1.000   56.000
1   2007-03-10       83         11      67  1.000   67.000
2   2007-02-10      111          9      66  1.000   66.000
3   2007-01-13      139         10      83  0.881   73.096
4   2006-12-23      160         10      88  0.793   69.787
5   2006-11-09      204          9      52  0.637   33.106
6   2006-10-22      222          8      66  0.582   38.408
7   2006-09-29      245          9      70  0.519   36.318
8   2006-09-16      258         11      68  0.486   33.063
9   2006-08-30      275          8      72  0.447   32.160
10  2006-02-11      475          5      65  0.165   10.698
11  2006-01-13      504          0      70  0.142    9.969
12  2006-01-02      515          0      64  0.135    8.627
13  2005-12-06      542          0      70  0.118    8.246
14  2005-11-29      549          0      70  0.114    7.963
15  2005-11-22      556          0      -1  0.110   -0.110
16  2005-11-01      577          0      -1  0.099   -0.099
17  2005-10-20      589          0      -1  0.093   -0.093
18  2005-09-27      612          0      -1  0.083   -0.083
19  2005-09-07      632          0      -1  0.075   -0.075
20  2005-06-12      719          0      69  0.049    3.360
21  2005-05-29      733          0      -1  0.045   -0.045
22  2005-05-02      760          0      -1  0.040   -0.040
23  2005-04-02      790          0      -1  0.034   -0.034
24  2005-03-13      810          0      -1  0.031   -0.031
25  2004-11-09      934          0      -1  0.017   -0.017

In [57]: df[df.line_race != 0]
Out[57]:
     line_date  daysago  line_race  rating    raw  wrating
0   2007-03-31       62         11      56  1.000   56.000
1   2007-03-10       83         11      67  1.000   67.000
2   2007-02-10      111          9      66  1.000   66.000
3   2007-01-13      139         10      83  0.881   73.096
4   2006-12-23      160         10      88  0.793   69.787
5   2006-11-09      204          9      52  0.637   33.106
6   2006-10-22      222          8      66  0.582   38.408
7   2006-09-29      245          9      70  0.519   36.318
8   2006-09-16      258         11      68  0.486   33.063
9   2006-08-30      275          8      72  0.447   32.160
10  2006-02-11      475          5      65  0.165   10.698

ACTUALIZACIÓN: Ahora que pandas 0.13 está fuera, otra forma de hacerlo es df.query('line_race != 0').

Phillip Cloud
fuente
df.query se ve muy útil! ¡Gracias! pandas.pydata.org/pandas-docs/version/0.13.1/generated/…
fantabolous
14
Buena actualización para query. Permite más ricos criterios de selección (por ejemplo, conjunto similar a las operaciones similares. df.query('variable in var_list')Donde 'var_list' es una lista de valores deseados)
Phile
1
¿Cómo se lograría esto si el nombre de la columna tiene un espacio en el nombre?
iNoob
2
queryno es muy útil si el nombre de la columna tiene un espacio en él.
Phillip Cloud
3
Yo evitaría tener espacios en las cabeceras con algo como estodf = df.rename(columns=lambda x: x.strip().replace(' ','_'))
Scientist1642
40

solo para agregar otra solución, particularmente útil si está utilizando los nuevos evaluadores de pandas, otras soluciones reemplazarán a los pandas originales y perderán a los evaluadores

df.drop(df.loc[df['line_race']==0].index, inplace=True)
desmond
fuente
1
cuál es el propósito de escribir índice e in situ. ¿Alguien puede explicar por favor?
heman123
2
¡Lee los documentos!
Federico Corazza
Creo que también deberíamos necesitarlo .reset_index()si alguien termina usando
accesores de
17

Si desea eliminar filas basadas en múltiples valores de la columna, puede usar:

df[(df.line_race != 0) & (df.line_race != 10)]

Para soltar todas las filas con valores 0 y 10 para line_race.

Robvh
fuente
¿Hay una manera más eficiente de hacer esto si tenía varios valores que deseaba eliminar, es decir, drop = [0, 10]y luego algo comodf[(df.line_race != drop)]
mikey hace
14

No obstante, la respuesta dada es correcta, ya que alguien de arriba dijo que puede usar, lo df.query('line_race != 0')que dependiendo de su problema es mucho más rápido. Altamente recomendado.

h3h325
fuente
Especialmente útil si tiene DataFramenombres de variables largos como yo (y, me atrevería a adivinar, todos en comparación con los dfutilizados para los ejemplos), porque solo tiene que escribirlo una vez.
ijoseph
9

Aunque las respuestas anteriores son casi similares a lo que voy a hacer, pero usar el método de índice no requiere usar otro método de indexación .loc (). Se puede hacer de manera similar pero precisa como

df.drop(df.index[df['line_race'] == 0], inplace = True)
Loochie
fuente
1
Solución en el lugar mejor para grandes conjuntos de datos o memoria limitada. +1
davmor
3

Otra forma de hacerlo. Puede que no sea la forma más eficiente, ya que el código parece un poco más complejo que el código mencionado en otras respuestas, pero sigue siendo una forma alternativa de hacer lo mismo.

  df = df.drop(df[df['line_race']==0].index)
Amruth Lakkavaram
fuente
1

Compilé y ejecuté mi código. Este es el código exacto. Puedes probarlo tú mismo.

data = pd.read_excel('file.xlsx')

Si tiene algún carácter especial o espacio en el nombre de la columna, puede escribirlo ''como en el código dado:

data = data[data['expire/t'].notnull()]
print (date)

Si solo hay un nombre de columna de cadena sin espacio ni caracteres especiales, puede acceder directamente a él.

data = data[data.expire ! = 0]
print (date)
Uzair
fuente
0

Simplemente agregue otra forma para DataFrame expandido en todas las columnas:

for column in df.columns:
   df = df[df[column]!=0]

Ejemplo:

def z_score(data,count):
   threshold=3
   for column in data.columns:
       mean = np.mean(data[column])
       std = np.std(data[column])
       for i in data[column]:
           zscore = (i-mean)/std
           if(np.abs(zscore)>threshold):
               count=count+1
               data = data[data[column]!=i]
   return data,count
Prateek Kumar Singh
fuente