Eu tenho um DataFrame do pandas e quero excluir linhas dele onde o comprimento da string em uma coluna específica é maior que 2.
Espero poder fazer isso (por esta resposta ):
df[(len(df['column name']) < 2)]
mas acabei de receber o erro:
KeyError: u'no item named False'
O que estou fazendo de errado?
(Nota: eu sei que posso usar df.dropna()
para me livrar de linhas que contenham alguma NaN
, mas não vi como remover linhas com base em uma expressão condicional.)
df[[(len(x) < 2) for x in df['column name']]]
mas a sua é muito melhor. Obrigado pela ajuda!df[df['column name'].map(lambda x: str(x)!=".")]
pandas 0.23.4
e python 3.6.copy()
no final, caso você queira editar posteriormente esse dataframe (por exemplo, atribuir novas colunas aumentaria o aviso "Um valor está tentando ser definido em uma cópia de uma fatia de um DataFrame").Para responder diretamente ao título original desta pergunta "Como excluir linhas de um DataFrame do pandas com base em uma expressão condicional" (que eu entendo não é necessariamente o problema do OP, mas pode ajudar outros usuários a encontrar essa pergunta), uma maneira de fazer isso é usar o método drop :
df = df.drop(some labels)
df = df.drop(df[<some boolean condition>].index)
Exemplo
Para remover todas as linhas em que a coluna 'score' é <50:
df = df.drop(df[df.score < 50].index)
Versão no local (conforme indicado nos comentários)
df.drop(df[df.score < 50].index, inplace=True)
Várias condições
(consulte Indexação booleana )
Para remover todas as linhas em que a coluna 'score' é <50 e> 20
df = df.drop(df[(df.score < 50) & (df.score > 20)].index)
fonte
reset_index()
). Descobri isso da maneira mais difícil quando o caminho para muitas linhas foi retirado do meu quadro de dados.test = df.drop(df[df['col1'].dtype == str].index)
, mas eu recebo o erroKeyError: False
Eu também tenteidf.drop(df[df.col1.dtype == str].index)
edf.drop(df[type(df.cleaned_norm_email) == str].index)
, mas nada parece funcionar? Alguém pode aconselhar. Obrigado! @Userdf[(df.score < 50) & (df.score > 20)]
como parte de sua resposta. Se você revertesse issodf = df[(df.score >= 50) | (df.score <= 20)]
, obteria sua resposta muito mais rapidamente.Você pode atribuir a
DataFrame
uma versão filtrada de si mesma:Isso é mais rápido que
drop
:fonte
Expandirei a solução genérica do @ User para fornecer uma
drop
alternativa gratuita. Isto é para pessoas direcionadas aqui com base no título da pergunta (não no problema do OP)Digamos que você queira excluir todas as linhas com valores negativos. Uma solução de revestimento é: -
Explicação passo a passo: -
Vamos gerar um quadro de dados de distribuição normal aleatória 5x5
Deixe a condição excluir negativos. Um DF booleano que satisfaça a condição: -
Uma série booleana para todas as linhas que satisfazem a condição Observe que, se algum elemento da linha falhar, a condição é marcada como falsa
Por fim, filtre as linhas do quadro de dados com base na condição
Você pode atribuí-lo novamente ao df para realmente excluir vs filtragem feita acima
df = df[(df > 0).all(axis=1)]
Isso pode ser facilmente estendido para filtrar linhas contendo NaN s (entradas não numéricas): -
df = df[(~df.isnull()).all(axis=1)]
Isso também pode ser simplificado para casos como: Exclua todas as linhas em que a coluna E é negativa
Gostaria de terminar com algumas estatísticas de criação de perfil sobre por que a
drop
solução do @ User é mais lenta que a filtragem baseada em coluna bruta: -Uma coluna é basicamente uma matriz,
Series
ou sejaNumPy
, pode ser indexada sem nenhum custo. Para as pessoas interessadas em como a organização da memória subjacente atua na velocidade de execução, aqui está um ótimo link para acelerar o Pandas :fonte
Nos pandas, você pode fazer o
str.len
seu limite e usar o resultado booleano para filtrá-lo.fonte
Se você deseja descartar linhas do quadro de dados com base em alguma condição complicada no valor da coluna, escrever isso da maneira mostrada acima pode ser complicado. Eu tenho a seguinte solução mais simples que sempre funciona. Vamos supor que você queira soltar a coluna com 'cabeçalho', para que essa coluna seja listada primeiro.
Agora aplique alguma função em todos os elementos da lista e coloque-a em uma série de panda:
no meu caso, eu estava apenas tentando obter o número de tokens:
agora adicione uma coluna extra com a série acima no quadro de dados:
agora podemos aplicar a condição na nova coluna, como:
fonte