Löschen der DataFrame-Zeile in Pandas basierend auf dem Spaltenwert

511

Ich habe den folgenden 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

Ich muss die Zeilen entfernen, in denen line_racegleich ist 0. Was ist der effizienteste Weg, dies zu tun?

TravisVOX
quelle

Antworten:

878

Wenn ich richtig verstehe, sollte es so einfach sein wie:

df = df[df.line_race != 0]
tshauck
quelle
16
Kostet dies mehr Speicher, wenn dfes groß ist? Oder kann ich es an Ort und Stelle tun?
Ziyuang
10
Lief es einfach auf einem dfmit 2M Reihen und es ging ziemlich schnell.
Dror
46
@vfxGer Wenn es ein Leerzeichen in der Spalte gibt, wie 'Linienrennen', dann können Sie einfach tundf = df[df['line race'] != 0]
Paul
3
Wie würden wir diesen Befehl ändern, wenn wir die gesamte Zeile löschen möchten, wenn der betreffende Wert in einer der Spalten in dieser Zeile gefunden wird?
Alex
3
Vielen Dank! Fwiw, für mich musste das seindf=df[~df['DATE'].isin(['2015-10-30.1', '2015-11-30.1', '2015-12-31.1'])]
citynorman
181

Aber für zukünftige Bypässe könnte man erwähnen, dass df = df[df.line_race != 0]dies nichts bewirkt, wenn versucht wird, nach None/ fehlenden Werten zu filtern .

Funktioniert:

df = df[df.line_race != 0]

Tut nichts:

df = df[df.line_race != None]

Funktioniert:

df = df[df.line_race.notnull()]
wunderkid2
quelle
4
Wie geht das, wenn wir den Spaltennamen nicht kennen?
Piyush S. Wanare
Könnte tun df = df[df.columns[2].notnull()], aber auf die eine oder andere Weise müssen Sie in der Lage sein, die Spalte irgendwie zu indizieren.
Erekalper
1
df = df[df.line_race != 0]löscht die Zeilen, setzt aber auch den Index nicht zurück. Wenn Sie also eine weitere Zeile in die df einfügen, wird diese möglicherweise am Ende nicht hinzugefügt. Ich würde empfehlen, den Index nach dieser Operation zurückzusetzen ( df = df.reset_index(drop=True))
the_new_james
Sie sollten niemals mit None mit dem ==zu startenden Operator vergleichen . stackoverflow.com/questions/3257919/…
Bram Vanroy
40

Der beste Weg, dies zu tun, ist die boolesche Maskierung:

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

UPDATE: Jetzt, da Pandas 0.13 herauskommt, ist eine andere Möglichkeit, dies zu tun df.query('line_race != 0').

Phillip Cloud
quelle
df.query sieht sehr nützlich aus! Vielen Dank! pandas.pydata.org/pandas-docs/version/0.13.1/generated/…
fantastisch
14
Gutes Update für query. Es ermöglicht umfangreichere Auswahlkriterien (z. B. df.query('variable in var_list')satzähnliche Operationen wie 'var_list' ist eine Liste der gewünschten Werte)
philE
1
Wie würde dies erreicht werden, wenn der Spaltenname ein Leerzeichen im Namen hat?
iNoob
2
queryist nicht sehr nützlich, wenn der Spaltenname ein Leerzeichen enthält.
Phillip Cloud
3
Ich würde vermeiden, Leerzeichen in den Überschriften mit so etwas zu habendf = df.rename(columns=lambda x: x.strip().replace(' ','_'))
Scientist1642
40

Nur um eine weitere Lösung hinzuzufügen, die besonders nützlich ist, wenn Sie die neuen Pandas-Prüfer verwenden, ersetzen andere Lösungen die ursprünglichen Pandas und verlieren die Prüfer

df.drop(df.loc[df['line_race']==0].index, inplace=True)
Desmond
quelle
1
Was ist der Zweck des Schreibens von Index und Inplace. Kann mir bitte jemand erklären?
heman123
2
Lesen Sie die Dokumente!
Federico Corazza
Ich denke, wir müssten es .reset_index()auch, wenn jemand Index-Accessoren verwendet
Ayush vor
16

Wenn Sie Zeilen basierend auf mehreren Werten der Spalte löschen möchten, können Sie Folgendes verwenden:

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

Alle Zeilen mit den Werten 0 und 10 für löschen line_race.

Robvh
quelle
Gibt es eine effizientere Möglichkeit, dies zu tun, wenn Sie mehrere Werte hatten, die Sie drop = [0, 10]df[(df.line_race != drop)]
löschen
14

Die gegebene Antwort ist dennoch richtig, da jemand oben sagte, dass Sie verwenden können, df.query('line_race != 0')was abhängig von Ihrem Problem viel schneller ist. Sehr empfehlenswert.

h3h325
quelle
Besonders hilfreich, wenn Sie lange haben DataFrame Variablennamen wie mich haben (und ich wage zu raten, jeder im Vergleich zu den dfBeispielen), weil Sie ihn nur einmal schreiben müssen.
Ijoseph
9

Obwohl die vorherige Antwort fast ähnlich ist wie die, die ich tun werde, erfordert die Verwendung der Indexmethode keine andere Indexierungsmethode .loc (). Dies kann auf ähnliche, aber präzise Weise erfolgen wie

df.drop(df.index[df['line_race'] == 0], inplace = True)
Loochie
quelle
1
In-Place-Lösung besser für große Datenmengen oder Speicherbeschränkungen. +1
Davmor
3

Ein anderer Weg, es zu tun. Möglicherweise nicht die effizienteste Methode, da der Code etwas komplexer aussieht als der in anderen Antworten erwähnte Code, aber dennoch eine alternative Methode, um dasselbe zu tun.

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

Fügen Sie einfach eine weitere Möglichkeit für DataFrame hinzu, die über alle Spalten erweitert wurde:

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

Beispiel:

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
quelle