Eliminazione della riga DataFrame in Panda in base al valore della colonna


512

Ho il seguente 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

Devo rimuovere le righe dove line_raceè uguale 0. Qual è il modo più efficiente per farlo?


Risposte:


879

Se sto capendo correttamente, dovrebbe essere semplice come:

df = df[df.line_race != 0]

16
Questo costerà più memoria se dfè grande? Oppure posso farlo sul posto?
ziyuang,

10
L'ho appena eseguito su un dffile con 2 M ed è andato abbastanza veloce.
Dror,

46
@vfxGer se c'è uno spazio nella colonna, come 'line race', allora puoi semplicemente farlodf = df[df['line race'] != 0]
Paul

3
Come modificheremmo questo comando se volessimo eliminare l'intera riga se il valore in questione si trova in una delle colonne di quella riga?
Alex,

3
Grazie! A seguire, per me questo doveva esseredf=df[~df['DATE'].isin(['2015-10-30.1', '2015-11-30.1', '2015-12-31.1'])]
citynorman il

182

Ma per eventuali futuri bypass si può menzionare che df = df[df.line_race != 0]non fa nulla quando si cerca di filtrare None/ valori mancanti.

Funziona:

df = df[df.line_race != 0]

Non fa nulla:

df = df[df.line_race != None]

Funziona:

df = df[df.line_race.notnull()]

4
come farlo se non conosciamo il nome della colonna?
Piyush S. Wanare,

Potrebbe df = df[df.columns[2].notnull()], ma in un modo o nell'altro devi essere in grado di indicizzare la colonna in qualche modo.
erekalper

1
df = df[df.line_race != 0]elimina le righe ma non reimposta l'indice. Quindi, quando aggiungi un'altra riga nel file df, questa potrebbe non essere aggiunta alla fine. Consiglio di ripristinare l'indice dopo df = df.reset_index(drop=True)
quell'operazione

Non dovresti mai confrontarti con Nessuno con l' ==operatore per iniziare. stackoverflow.com/questions/3257919/...
Bram Vanroy

40

Il modo migliore per farlo è con il mascheramento 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

AGGIORNAMENTO: Ora che Panda 0.13 è uscito, un altro modo per farlo è df.query('line_race != 0').



14
Buon aggiornamento per query. Permette criteri di selezione più ricchi (ad es. Operazioni simili a set come df.query('variable in var_list')dove 'var_list' è un elenco di valori desiderati)
philE

1
come verrebbe realizzato se il nome della colonna avesse uno spazio nel nome?
iNoob,

2
querynon è molto utile se il nome della colonna contiene uno spazio.
Phillip Cloud,

3
Eviterei di avere spazi nelle intestazioni con qualcosa del generedf = df.rename(columns=lambda x: x.strip().replace(' ','_'))
Scienziato

40

solo per aggiungere un'altra soluzione, particolarmente utile se si utilizzano i nuovi valutatori di Panda, altre soluzioni sostituiranno i Panda originali e perderanno i valutatori

df.drop(df.loc[df['line_race']==0].index, inplace=True)

1
qual è lo scopo di scrivere indice e sul posto. Qualcuno può spiegare per favore?
heman123


Penso che dovremmo farlo .reset_index()anche se qualcuno finisce per usare gli
accessi

17

Se si desidera eliminare le righe in base a più valori della colonna, è possibile utilizzare:

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

Per eliminare tutte le righe con i valori 0 e 10 per line_race.


C'è un modo più efficiente per farlo se avessi più valori che volevi eliminare, drop = [0, 10]e quindi qualcosa del generedf[(df.line_race != drop)]
mikey

14

La risposta data è corretta, tuttavia, come qualcuno sopra ha detto che puoi usare df.query('line_race != 0')quale a seconda del tuo problema è molto più veloce. Altamente raccomandato.


Particolarmente utile se hai DataFramenomi di variabili lunghe come me (e, mi permetto di indovinare, tutti rispetto a quelli dfusati per gli esempi), perché devi scriverlo solo una volta.
ijoseph,

9

Sebbene la risposta precedente sia quasi simile a quello che sto per fare, ma l'utilizzo del metodo index non richiede l'utilizzo di un altro metodo di indicizzazione .loc (). Può essere fatto in modo simile ma preciso come

df.drop(df.index[df['line_race'] == 0], inplace = True)

1
Soluzione sul posto migliore per set di dati di grandi dimensioni o memoria limitata. +1
davmor

3

Un altro modo di farlo. Potrebbe non essere il modo più efficiente in quanto il codice sembra un po 'più complesso del codice menzionato in altre risposte, ma comunque un modo alternativo di fare la stessa cosa.

  df = df.drop(df[df['line_race']==0].index)

1

Ho compilato ed eseguito il mio codice. Questo è un codice preciso. Puoi provarlo tu stesso.

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

Se hai un carattere o uno spazio speciale nel nome della colonna, puoi scriverlo ''come nel codice indicato:

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

Se esiste un solo nome di colonna di stringa singola senza spazio o carattere speciale, puoi accedervi direttamente.

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

0

Basta aggiungere un altro modo per DataFrame espanso su tutte le colonne:

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

Esempio:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.