Excluindo a linha DataFrame no Pandas com base no valor da coluna

511

Eu tenho o seguinte 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

Eu preciso remover as linhas onde line_raceé igual a 0. Qual é a maneira mais eficiente de fazer isso?

TravisVOX
fonte

Respostas:

878

Se estou entendendo corretamente, deve ser tão simples quanto:

df = df[df.line_race != 0]
tshauck
fonte
16
Isso custará mais memória se dffor grande? Ou posso fazê-lo no local?
ziyuang
10
Apenas executei em um dfcom 2M linhas e foi muito rápido.
Dror
46
@vfxGer se houver um espaço na coluna, como 'raça linha', então você pode apenas fazerdf = df[df['line race'] != 0]
Paul
3
Como modificaríamos esse comando se desejássemos excluir a linha inteira se o valor em questão for encontrado em qualquer uma das colunas dessa linha?
Alex
3
Obrigado! Fwiw, para mim isso tinha que serdf=df[~df['DATE'].isin(['2015-10-30.1', '2015-11-30.1', '2015-12-31.1'])]
citynorman
182

Mas para futuros ignorantes, você poderia mencionar que df = df[df.line_race != 0]não faz nada ao tentar filtrar por None/ valores ausentes.

Funciona:

df = df[df.line_race != 0]

Não faz nada:

df = df[df.line_race != None]

Funciona:

df = df[df.line_race.notnull()]
wonderkid2
fonte
4
como fazer isso se não soubermos o nome da coluna?
Piyush S. Wanare
Poderia funcionar df = df[df.columns[2].notnull()], mas de uma forma ou de outra você precisa ser capaz de indexar a coluna de alguma forma.
Erekalper #
1
df = df[df.line_race != 0]descarta as linhas, mas também não redefine o índice. Portanto, quando você adiciona outra linha no df, ela pode não ser adicionada no final. Eu recomendo redefinir o índice após essa operação ( df = df.reset_index(drop=True))
the_new_james 17/07/1919
Você nunca deve comparar a Nenhum com o ==operador para iniciar. stackoverflow.com/questions/3257919/…
Bram Vanroy
40

A melhor maneira de fazer isso é com o mascaramento 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

ATUALIZAÇÃO: Agora que o pandas 0.13 está lançado, outra maneira de fazer isso é df.query('line_race != 0').

Phillip Cloud
fonte
O df.query parece muito útil! Obrigado! pandas.pydata.org/pandas-docs/version/0.13.1/generated/...
fantabolous
14
Boa atualização para query. Ele permite critérios de seleção mais ricos (por exemplo, operações de conjunto, como df.query('variable in var_list')onde 'var_list' é uma lista dos valores desejados)
philE
1
como isso seria alcançado se o nome da coluna tivesse um espaço no nome?
INoob #
2
querynão é muito útil se o nome da coluna tiver um espaço nela.
Phillip Cloud
3
Gostaria de evitar ter espaços nos cabeçalhos com algo parecido com issodf = df.rename(columns=lambda x: x.strip().replace(' ','_'))
Scientist1642
40

apenas para adicionar outra solução, particularmente útil se você estiver usando os novos avaliadores de pandas, outras soluções substituirão os pandas originais e perderão os avaliadores

df.drop(df.loc[df['line_race']==0].index, inplace=True)
Desmond
fonte
1
qual é o objetivo de escrever índice e local. Alguém pode explicar por favor?
precisa saber é o seguinte
2
Leia os documentos!
Federico Corazza
Eu acho que precisamos .reset_index()também se alguém acabar usando acessadores de índice
Ayush
17

Se você deseja excluir linhas com base em vários valores da coluna, você pode usar:

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

Para eliminar todas as linhas com os valores 0 e 10 para line_race.

Robvh
fonte
Existe uma maneira mais eficiente de fazer isso, se você tiver vários valores que deseja descartar, ou seja, drop = [0, 10]e algo comodf[(df.line_race != drop)]
mikey
14

A resposta dada está correta, no entanto, como alguém acima disse que você pode usar o df.query('line_race != 0')que, dependendo do seu problema, é muito mais rápido. Altamente recomendado.

h3h325
fonte
Especialmente útil se você tiver DataFramenomes de variáveis longos como eu (e, arrisco-me a adivinhar, todo mundo em comparação com o dfusado para exemplos), porque você só precisa escrevê-lo uma vez.
precisa saber é
9

Embora a resposta anterior seja quase semelhante ao que vou fazer, mas o uso do método index não requer o uso de outro método de indexação .loc (). Isso pode ser feito de maneira semelhante, mas precisa, como

df.drop(df.index[df['line_race'] == 0], inplace = True)
Loochie
fonte
1
Solução no local melhor para grandes conjuntos de dados ou memória restrita. 1
davmor 24/10/19
3

Outra maneira de fazer isso. Pode não ser a maneira mais eficiente, pois o código parece um pouco mais complexo que o código mencionado em outras respostas, mas ainda assim é uma maneira alternativa de fazer a mesma coisa.

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

Compilei e executei meu código. Este é um código preciso. Você pode tentar por conta própria.

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

Se você tiver algum caractere ou espaço especial no nome da coluna, poderá escrevê-lo ''como no código fornecido:

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

Se houver apenas um nome de coluna de sequência única sem nenhum espaço ou caractere especial, você poderá acessá-lo diretamente.

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

Apenas adicionando outra maneira para o DataFrame expandido em todas as colunas:

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

Exemplo:

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
fonte