Procure por "não contém" em um DataFrame em pandas

142

Eu fiz algumas pesquisas e não consigo descobrir como filtrar um dataframe df["col"].str.contains(word), no entanto, estou me perguntando se existe uma maneira de fazer o inverso: filtrar um dataframe pelo elogio desse conjunto. por exemplo: para o efeito de !(df["col"].str.contains(word)).

Isso pode ser feito através de um DataFramemétodo?

stites
fonte

Respostas:

264

Você pode usar o operador invert (~) (que age como um não para dados booleanos):

new_df = df[~df["col"].str.contains(word)]

, onde new_dfé a cópia retornada pelo RHS.

contém também aceita uma expressão regular ...


Se o exposto acima gera um ValueError, é provável que o motivo seja porque você misturou tipos de dados, então use na=False:

new_df = df[~df["col"].str.contains(word, na=False)]

Ou,

new_df = df[df["col"].str.contains(word) == False]
Andy Hayden
fonte
1
Perfeito! Estou familiarizado com o SQL com regex e pensei que era diferente no Python - vi muitos artigos re.compliese disse a mim mesmo que chegaria a isso mais tarde. Parece que eu super ajustei a pesquisa e é exatamente como você diz
:)
6
Talvez um exemplo completo seja útil: df[~df.col.str.contains(word)]retorna uma cópia do quadro de dados original com linhas excluídas correspondentes à palavra.
Dennis Golomazov
45

Eu estava tendo problemas com o símbolo not (~) também, então aqui está outra maneira de outro thread do StackOverflow :

df[df["col"].str.contains('this|that')==False]
nanselm2
fonte
Pode ser combinado assim? df[df["col1"].str.contains('this'|'that')==False and df["col2"].str.contains('foo'|'bar')==True]? Obrigado!
Tommy.carstensen
Sim você pode. A sintaxe é explicada aqui: stackoverflow.com/questions/22086116/…
tommy.carstensen
Não se esqueça que, se queremos rwmove linhas que contêm "|" devemos usar "\" como df = df[~df["col"].str.contains('\|')]
Amir
9

Você pode usar o Apply e o Lambda para selecionar linhas em que uma coluna contém qualquer coisa em uma lista. Para o seu cenário:

df[df["col"].apply(lambda x:x not in [word1,word2,word3])]
Arash
fonte
6

Eu tive que me livrar dos valores NULL antes de usar o comando recomendado por Andy acima. Um exemplo:

df = pd.DataFrame(index = [0, 1, 2], columns=['first', 'second', 'third'])
df.ix[:, 'first'] = 'myword'
df.ix[0, 'second'] = 'myword'
df.ix[2, 'second'] = 'myword'
df.ix[1, 'third'] = 'myword'
df

    first   second  third
0   myword  myword   NaN
1   myword  NaN      myword 
2   myword  myword   NaN

Agora executando o comando:

~df["second"].str.contains(word)

Estou tendo o erro a seguir:

TypeError: bad operand type for unary ~: 'float'

Eu me livrei dos valores NULL usando dropna () ou fillna () primeiro e tentei o comando novamente sem nenhum problema.

Shoresh
fonte
1
Você também pode usar ~df["second"].astype(str).str.contains(word)para forçar a conversão para str. Veja stackoverflow.com/questions/43568760/…
David C
1
@Shoresh também podemos usar na = False como solução deste problema
Vishav Gupta
5

Espero que as respostas já estejam postadas

Estou adicionando a estrutura para encontrar várias palavras e negar as do dataFrame .

Aqui 'word1','word2','word3','word4'= lista de padrões a serem pesquisados

df = DataFrame

column_a = Um nome de coluna do DataFrame df

Search_for_These_values = ['word1','word2','word3','word4'] 

pattern = '|'.join(Search_for_These_values)

result = df.loc[~(df['column_a'].str.contains(pattern, case=False)]
Nursnaaz
fonte
3

Adicional à resposta do nanselm2, você pode usar em 0vez de False:

df["col"].str.contains(word)==0
Sub-10
fonte
parece que isso também removerá todas as linhas comNaN
bshelt141