3 Métodos de Como selecionar linhas de um DataFrame com base nos valores da coluna?
Como posso selecionar linhas de um DataFrame com base em valores em alguma coluna em Pandas?
No SQL, eu usaria:
SELECT *
FROM table
WHERE column_name = some_value
Indice
Veja abaixo 3 Métodos:
Método 1
Para selecionar linhas cujo valor da coluna é igual a um escalar, some_value
, usar ==
:
df.loc[df['column_name'] == some_value]
Para selecionar linhas cujo valor da coluna está em iterável, some_values
, usar isin
:
df.loc[df['column_name'].isin(some_values)]
Combine várias condições com &
:
df.loc[(df['column_name'] >= A) & (df['column_name'] <= B)]
Observe os parênteses. Devido ao Python’s regras de precedência do operador, &
liga mais firmemente do que <=
e >=
. Assim, os parênteses no último exemplo são necessários. Sem os parênteses
df['column_name'] >= A & df['column_name'] <= B
é analisado como
df['column_name'] >= (A & df['column_name']) <= B
que resulta em um O valor da verdade de uma série é um erro ambíguo.
Para selecionar linhas cujo valor da coluna não é igual some_value
, usar !=
:
df.loc[df['column_name'] != some_value]
isin
retorna uma série booleana, portanto, para selecionar linhas cujo valor é não em some_values
, negue a série booleana usando ~
:
df.loc[~df['column_name'].isin(some_values)]
Por exemplo,
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
'B': 'one one two three two two one three'.split(),
'C': np.arange(8), 'D': np.arange(8) * 2})
print(df)
# A B C D
# 0 foo one 0 0
# 1 bar one 1 2
# 2 foo two 2 4
# 3 bar three 3 6
# 4 foo two 4 8
# 5 bar two 5 10
# 6 foo one 6 12
# 7 foo three 7 14
print(df.loc[df['A'] == 'foo'])
rendimentos
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
Se você tiver vários valores que deseja incluir, coloque-os em um listar ( ou mais geralmente, qualquer iterável ) e usar isin
:
print(df.loc[df['B'].isin(['one','three'])])
rendimentos
A B C D
0 foo one 0 0
1 bar one 1 2
3 bar three 3 6
6 foo one 6 12
7 foo three 7 14
Observe, no entanto, que se você deseja fazer isso muitas vezes, é mais eficiente faça um índice primeiro e depois use df.loc
:
df = df.set_index(['B'])
print(df.loc['one'])
rendimentos
A C D
B
one foo 0 0
one bar 1 2
one foo 6 12
ou, para incluir vários valores do uso do índice df.index.isin
:
df.loc[df.index.isin(['one','two'])]
rendimentos
A C D
B
one foo 0 0
one bar 1 2
two foo 2 4
two foo 4 8
two bar 5 10
one foo 6 12
Método 2
Os pandas equivalentes a
select * from table where column_name = some_value
é
table[table.column_name == some_value]
Várias condições:
table[(table.column_name == some_value) | (table.column_name2 == some_value2)]
ou
table.query('column_name == some_value | column_name2 == some_value2')
Exemplo de código
import pandas as pd
# Create data set
d = {'foo':[100, 111, 222],
'bar':[333, 444, 555]}
df = pd.DataFrame(d)
# Full dataframe:
df
# Shows:
# bar foo
# 0 333 100
# 1 444 111
# 2 555 222
# Output only the row(s) in df where foo is 222:
df[df.foo == 222]
# Shows:
# bar foo
# 2 555 222
No código acima, é a linha df[df.foo == 222]
que fornece as linhas com base no valor da coluna, 222
neste caso.
Várias condições também são possíveis:
df[(df.foo == 222) | (df.bar == 444)]
# bar foo
# 1 444 111
# 2 555 222
Mas, nesse ponto, eu recomendaria usar o consulta função, pois é menos detalhado e produz o mesmo resultado:
df.query('foo == 222 | bar == 444')
Método 3
Mais flexibilidade usando .query
com pandas > = 0,25.0:
Como pandas > = 0.25.0, podemos usar o query
método para filtrar quadros de dados com métodos de pandas e até nomes de colunas que possuem espaços. Normalmente, os espaços nos nomes das colunas causariam um erro, mas agora podemos resolver isso usando um backtick ( `) – veja GitHub:
# Example dataframe
df = pd.DataFrame({'Sender email':['ex@example.com', "reply@shop.com", "buy@shop.com"]})
Sender email
0 ex@example.com
1 reply@shop.com
2 buy@shop.com
Usando .query
com método str.endswith
:
df.query('`Sender email`.str.endswith("@shop.com")')
Saída
Sender email
1 reply@shop.com
2 buy@shop.com
Também podemos usar variáveis locais prefixando-as com um @
em nossa consulta:
domain = 'shop.com'
df.query('`Sender email`.str.endswith(@domain)')
Saída
Sender email
1 reply@shop.com
2 buy@shop.com
Conteúdo traduzido do stackoverflow
How do I select rows from a DataFrame based on column values?
Começando com python?
Veja mais sobre: 10 dicas e truques essenciais do Python para programadores