Como soltar uma lista de linhas do dataframe do Pandas?

258

Eu tenho um df de dataframe:

>>> df
                  sales  discount  net_sales    cogs
STK_ID RPT_Date                                     
600141 20060331   2.709       NaN      2.709   2.245
       20060630   6.590       NaN      6.590   5.291
       20060930  10.103       NaN     10.103   7.981
       20061231  15.915       NaN     15.915  12.686
       20070331   3.196       NaN      3.196   2.710
       20070630   7.907       NaN      7.907   6.459

Então eu quero soltar linhas com certos números de sequência indicados em uma lista, suponha que aqui fique o seguinte [1,2,4],:

                  sales  discount  net_sales    cogs
STK_ID RPT_Date                                     
600141 20060331   2.709       NaN      2.709   2.245
       20061231  15.915       NaN     15.915  12.686
       20070630   7.907       NaN      7.907   6.459

Como ou que função pode fazer isso?

Grande erro
fonte
apenas para esclarecer, esta pergunta é sobre descartar linhas com valores de índice específicos. seu uso de [1,2,4] é apontar para as linhas que sobraram após descartar. Existem respostas abaixo que fazem isso.
alquimia

Respostas:

386

Use DataFrame.drop e passe uma série de rótulos de índice:

In [65]: df
Out[65]: 
       one  two
one      1    4
two      2    3
three    3    2
four     4    1


In [66]: df.drop(df.index[[1,3]])
Out[66]: 
       one  two
one      1    4
three    3    2
Theodros Zelleke
fonte
18
+1 Além disso, Eliminando a última linha df.drop (df.tail (1) .index)
Nasser Al-Wohaibi
15
Essa resposta funciona apenas se df.index.unique () for o mesmo que df.index, que não é um requisito para um DataFrame do Pandas. Alguém tem uma solução quando não é garantido que os valores de df.index sejam únicos?
J Jones
2
isso não permite que você indexe o próprio nome do índice
ingrid
45
Pessoal, em exemplos, se você quiser ser claro, não use as mesmas strings para linhas e colunas. Isso é bom para quem realmente já conhece suas coisas. Frustrante para quem está tentando aprender.
gseattle
2
recém-chegados ao python: observe que, se você quiser soltar essas linhas e salvá-las no mesmo quadro de dados (local), também precisará adicionar axis=0(0 = linhas, 1 = colunas) e inplace=Truecomo em df.drop(df.index[[1,3]], axis=0, inplace=True). @mezzanaccio, se você especificamente saber quais índices que deseja substituir (e também usando o seu 0 a n exemplo):df.drop(df.index[range(0, n)], axis=0, inplace=True)
mrbTT
47

Se o DataFrame for enorme e o número de linhas a serem descartadas também for grande, a simples remoção por índice df.drop(df.index[])leva muito tempo.

No meu caso, tenho um DataFrame multi-indexado de floats 100M rows x 3 colse preciso remover 10klinhas dele. O método mais rápido que encontrei é, de maneira bastante intuitiva, para takeas linhas restantes.

Let indexes_to_dropSer uma matriz de índices posicionais para cair ( [1, 2, 4]na questão).

indexes_to_keep = set(range(df.shape[0])) - set(indexes_to_drop)
df_sliced = df.take(list(indexes_to_keep))

No meu caso, isso levou 20.5s, enquanto o simples df.droppegou 5min 27se consumiu muita memória. O DataFrame resultante é o mesmo.

Dennis Golomazov
fonte
43

Você também pode passar para DataFrame.drop o próprio rótulo (em vez de Série de rótulos de índice):

In[17]: df
Out[17]: 
            a         b         c         d         e
one  0.456558 -2.536432  0.216279 -1.305855 -0.121635
two -1.015127 -0.445133  1.867681  2.179392  0.518801

In[18]: df.drop('one')
Out[18]: 
            a         b         c         d         e
two -1.015127 -0.445133  1.867681  2.179392  0.518801

O que equivale a:

In[19]: df.drop(df.index[[0]])
Out[19]: 
            a         b         c         d         e
two -1.015127 -0.445133  1.867681  2.179392  0.518801
danielhadar
fonte
1
df.drop (df.index [0]) também funciona. quer dizer, sem necessidade de square_brackets duplos (com pandas 0.18.1, pelo menos)
tagoma
23

Eu resolvi isso de uma maneira mais simples - apenas em 2 etapas.

Etapa 1: primeiro forme um quadro de dados com linhas / dados indesejados.

Etapa 2: use o índice desse quadro de dados indesejado para eliminar as linhas do quadro de dados original.

Exemplo:

Suponha que você tenha um dataframe df com tantas colunas, incluindo 'Age', que é um número inteiro. Agora, digamos que você queira descartar todas as linhas com 'Idade' como número negativo.

Etapa 1: df_age_negative = df [df ['Idade'] <0]

Etapa 2: df = df.drop (df_age_negative.index, axis = 0)

Espero que isso seja muito mais simples e ajude você.

Krishnaprasad Challuru
fonte
1
+1, esta é a única resposta que mostra como remover uma linha selecionando uma coluna diferente da primeira.
Alejo Bernardin
10

Se eu quiser soltar uma linha que tenha digamos index x, eu faria o seguinte:

df = df[df.index != x]

Se eu quiser soltar vários índices (digamos que esses índices estejam na lista unwanted_indices), eu faria:

desired_indices = [i for i in len(df.index) if i not in unwanted_indices]
desired_df = df.iloc[desired_indices]
Divyansh
fonte
6

Aqui está um exemplo um pouco específico, eu gostaria de mostrar. Digamos que você tenha muitas entradas duplicadas em algumas de suas linhas. Se você tiver entradas de sequência, poderá facilmente usar métodos de sequência para encontrar todos os índices a serem descartados.

ind_drop = df[df['column_of_strings'].apply(lambda x: x.startswith('Keyword'))].index

E agora para descartar essas linhas usando seus índices

new_df = df.drop(ind_drop)
cyber-math
fonte
3

Em um comentário à resposta de @ theodros-zelleke, @ j-jones perguntou sobre o que fazer se o índice não for único. Eu tive que lidar com essa situação. O que fiz foi renomear as duplicatas no índice antes de drop()ligar para:

dropped_indexes = <determine-indexes-to-drop>
df.index = rename_duplicates(df.index)
df.drop(df.index[dropped_indexes], inplace=True)

onde rename_duplicates()é uma função que eu defini que passou pelos elementos do índice e renomeou as duplicatas. Usei o mesmo padrão de renomeação pd.read_csv()usado nas colunas, ou seja, "%s.%d" % (name, count)onde nameestá o nome da linha e countquantas vezes ocorreu anteriormente.

mepstein
fonte
1

Determinando o índice a partir do booleano, conforme descrito acima, por exemplo

df[df['column'].isin(values)].index

pode consumir mais memória do que determinar o índice usando esse método

pd.Index(np.where(df['column'].isin(values))[0])

aplicado assim

df.drop(pd.Index(np.where(df['column'].isin(values))[0]), inplace = True)

Este método é útil ao lidar com quadros de dados grandes e memória limitada.

Adam Zeldin
fonte
0

Use apenas o argumento Argumento para descartar a linha: -

df.drop(index = 2, inplace = True)

Para várias linhas: -

df.drop(index=[1,3], inplace = True)
kamran kausar
fonte
0

Considere um exemplo de quadro de dados

df =     
index    column1
0           00
1           10
2           20
3           30

queremos soltar a segunda e a terceira linhas de índice.

Abordagem 1:

df = df.drop(df.index[2,3])
 or 
df.drop(df.index[2,3],inplace=True)
print(df)

df =     
index    column1
0           00
3           30

 #This approach removes the rows as we wanted but the index remains unordered

Abordagem 2

df.drop(df.index[2,3],inplace=True,ignore_index=True)
print(df)
df =     
index    column1
0           00
1           30
#This approach removes the rows as we wanted and resets the index. 
Continente
fonte