Suppression de la ligne DataFrame dans Pandas en fonction de la valeur de la colonne

512

J'ai le DataFrame suivant:

             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

J'ai besoin de supprimer les lignes où line_raceest égal à 0. Quelle est la manière la plus efficace de procéder?

TravisVOX
la source

Réponses:

879

Si je comprends bien, cela devrait être aussi simple que:

df = df[df.line_race != 0]
tshauck
la source
16
Cela coûtera-t-il plus de mémoire s'il dfest volumineux? Ou puis-je le faire sur place?
ziyuang
10
Je l'ai juste couru sur df2M de lignes et c'est allé assez vite.
Dror
46
@vfxGer s'il y a un espace dans la colonne, comme 'course en ligne', alors vous pouvez le fairedf = df[df['line race'] != 0]
Paul
3
Comment modifierions-nous cette commande si nous voulions supprimer la ligne entière si la valeur en question se trouve dans l'une des colonnes de cette ligne?
Alex
3
Merci! Fwiw, pour moi, cela devait êtredf=df[~df['DATE'].isin(['2015-10-30.1', '2015-11-30.1', '2015-12-31.1'])]
citynorman
182

Mais pour tout futur contourneur, vous pourriez mentionner que df = df[df.line_race != 0]cela ne fait rien lorsque vous essayez de filtrerNone les valeurs / manquantes.

Fonctionne:

df = df[df.line_race != 0]

Ne fait rien:

df = df[df.line_race != None]

Fonctionne:

df = df[df.line_race.notnull()]
wonderkid2
la source
4
comment faire si on ne connaît pas le nom de la colonne?
Piyush S. Wanare
Cela pourrait être le cas df = df[df.columns[2].notnull()], mais d'une manière ou d'une autre, vous devez pouvoir indexer la colonne d'une manière ou d'une autre.
erekalper
1
df = df[df.line_race != 0]supprime les lignes mais ne réinitialise pas non plus l'index. Ainsi, lorsque vous ajoutez une autre ligne dans le df, elle peut ne pas s'ajouter à la fin. Je recommanderais de réinitialiser l'index après cette opération ( df = df.reset_index(drop=True))
the_new_james
Vous ne devez jamais comparer à Aucun avec l' ==opérateur pour commencer. stackoverflow.com/questions/3257919/…
Bram Vanroy
40

La meilleure façon de le faire est avec le masquage booléen:

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

MISE À JOUR: Maintenant que pandas 0.13 est sorti, une autre façon de le faire est df.query('line_race != 0').

Phillip Cloud
la source
df.query semble très utile! Merci! pandas.pydata.org/pandas-docs/version/0.13.1/generated/…
fantabolous
14
Bonne mise à jour pour query. Il permet des critères de sélection plus riches (par exemple, des opérations de type ensemble comme df.query('variable in var_list')où 'var_list' est une liste de valeurs souhaitées)
philE
1
comment cela serait-il possible si le nom de la colonne a un espace dans le nom?
iNoob
2
queryn'est pas très utile si le nom de la colonne contient un espace.
Phillip Cloud
3
J'éviterais d'avoir des espaces dans les en-têtes avec quelque chose comme çadf = df.rename(columns=lambda x: x.strip().replace(' ','_'))
Scientist1642
40

juste pour ajouter une autre solution, particulièrement utile si vous utilisez les nouveaux évaluateurs de pandas, d'autres solutions remplaceront les pandas originaux et perdront les évaluateurs

df.drop(df.loc[df['line_race']==0].index, inplace=True)
desmond
la source
1
quel est le but de l'écriture d'index et en place. Quelqu'un peut-il expliquer s'il vous plaît?
heman123
2
Lisez les documents!
Federico Corazza
Je pense que nous aurions besoin de le faire .reset_index()aussi si quelqu'un finit par utiliser des accesseurs d'index
Ayush
17

Si vous souhaitez supprimer des lignes en fonction de plusieurs valeurs de la colonne, vous pouvez utiliser:

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

Pour supprimer toutes les lignes avec les valeurs 0 et 10 pour line_race.

Robvh
la source
Existe-t-il un moyen plus efficace de le faire si vous aviez plusieurs valeurs à supprimer, c'est-à-dire drop = [0, 10]quelque chose commedf[(df.line_race != drop)]
Mikey il y a
14

La réponse donnée est néanmoins correcte car quelqu'un ci-dessus a dit que vous pouvez utiliser df.query('line_race != 0')ce qui, en fonction de votre problème, est beaucoup plus rapide. Recommande fortement.

h3h325
la source
Particulièrement utile si vous avez DataFramedes noms de variable longs comme moi (et, j'ose le deviner, tout le monde par rapport à celui dfutilisé pour les exemples), car vous ne devez l'écrire qu'une seule fois.
ijoseph
9

Bien que la réponse précédente soit presque similaire à ce que je vais faire, mais l'utilisation de la méthode d'indexation ne nécessite pas l'utilisation d'une autre méthode d'indexation .loc (). Cela peut être fait d'une manière similaire mais précise

df.drop(df.index[df['line_race'] == 0], inplace = True)
Loochie
la source
1
Solution en place meilleure pour les grands ensembles de données ou la mémoire contrainte. +1
davmor
3

Une autre façon de le faire. Peut-être pas le moyen le plus efficace car le code semble un peu plus complexe que le code mentionné dans d'autres réponses, mais toujours une manière alternative de faire la même chose.

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

J'ai compilé et exécuté mon code. C'est un code précis. Vous pouvez l'essayer vous-même.

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

Si vous avez un caractère spécial ou un espace dans le nom de la colonne, vous pouvez l'écrire ''comme dans le code donné:

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

S'il n'y a qu'un seul nom de colonne de chaîne sans espace ni caractère spécial, vous pouvez y accéder directement.

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

Il suffit d'ajouter une autre façon pour DataFrame développé sur toutes les colonnes:

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

Exemple:

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
la source