Iloc vs Loc no Pandas: Um Guia com Exemplos

Uma daquelas coisas irritantes que todos nós estamos tentando entender quando aprendemos Pandas é a distinção entre .loc e .iloc.

Vamos acabar com essa confusão e esclarecer a diferença entre esses dois métodos. Vou dar muitos exemplos, e espero que a distinção fique muito mais clara até o final deste blog.

O Que São .loc e .iloc no Pandas?

Ambos .loc e .iloc são atributos essenciais dos DataFrames do Pandas, e ambos são usados para selecionar subconjuntos específicos de dados. Seu propósito é acessar e permitir a manipulação de uma parte específica do DataFrame em vez do DataFrame inteiro.

Recurso

.loc

.iloc

Sintaxe

df.loc[row_indexer, column_indexer]

df.iloc[row_indexer, column_indexer]

Método de Indexação

Indexação baseada em rótulos

Indexação baseada em posição

Usado para Referência

Rótulos de linhas e colunas

Índices numéricos de linhas e colunas (começando do 0)

Como podemos ver na tabela, a sintaxe parece muito semelhante. A diferença está em como usamos os argumentos row_indexer e column_indexer. Isso ocorre porque os dois métodos oferecem abordagens diferentes para indexar os dados: enquanto o .loc indexa com base nos nomes dos rótulos, o .iloc utiliza o índice de posição numérica das linhas e colunas como argumentos.

Vamos examinar cada um dos dois métodos em detalhes, começando pelo .loc.

Usando .loc: Seleção por Etiquetas

Para ilustrar os conceitos, vamos considerar um banco de dados de clientes hipotético representado por este DataFrame chamado df, com o ID do Cliente representando o índice da linha:

ID do Cliente

Nome

País

Região

Idade

C123

João Silva

Estados Unidos

América do Norte

67

C234

Petra Müller

Alemanha

Europa

51

C345

Ali Khan

Paquistão

Ásia

19

C456

Maria Gonzalez

México

América do Norte

26

C567

David Lee

China

Ásia

40

Existem quatro maneiras principais de selecionar linhas com .loc. Estas incluem:

  • Selecionando uma única linha
  • Selecionando várias linhas
  • Selecionando um intervalo de linhas
  • Seleção condicional de linhas

Selecionando uma única linha usando .loc

Para selecionar uma única linha, usamos o rótulo da linha que queremos recuperar como row_indexer. De acordo com isso, a sintaxe se parece com isto: df.loc['row_label']. Vamos usar isso para exibir todas as informações sobre nosso cliente Ali Khan:

df.loc['C345']

C345

 

Nome

Ali Khan

País

Paquistão

Região

Ásia

Idade

19

Selecionando várias linhas usando .loc

Se quisermos selecionar várias linhas que não necessariamente seguem uma à outra em ordem, precisamos passar uma lista de seus rótulos de linha como argumento row_indexer. Isso significa que precisamos usar não uma, mas duas pares de colchetes: um para a sintaxe regular .loc e outro para a lista de rótulos.

A linha df.loc[['row_label_1', 'row_label_2']] retornará as duas linhas do DataFrame df especificadas na lista. Vamos supor que quiséssemos saber não apenas as informações sobre Ali Khan, mas também sobre David Lee:

df.loc[['C345', 'C567']]

ID do Cliente

Nome

País

Região

Idade

C345

Ali Khan

Paquistão

Ásia

19

C567

David Lee

China

Ásia

40

Selecionando uma fatia de linhas usando .loc

Podemos selecionar um intervalo de linhas passando os rótulos da primeira e da última linha com dois pontos entre eles: df.loc['row_label_start':'row_label_end']. Poderíamos exibir as quatro primeiras linhas do nosso DataFrame assim:

df.loc['C123' : 'C456']

ID do Cliente

Nome

País

Região

Data de Inscrição

C123

John Doe

Estados Unidos

América do Norte

67

C234

Petra Müller

Alemanha

Europa

51

C345

Ali Khan

Paquistão

Ásia

19

C456

Maria Gonzalez

México

América do Norte

26

Aqui estão duas coisas a ter em mente:

  1. A saída inclui a linha especificada em row_label_end. Isso é diferente em .iloc, que abordaremos mais tarde.
  2. Usamos apenas um par de colchetes, mesmo que queiramos recuperar várias linhas. Não usamos uma lista para especificar as várias linhas, então usar dois colchetes retornaria um SyntaxError.

Seleção condicional de linhas usando .loc

Também podemos retornar linhas com base em uma expressão condicional. Podemos filtrar todas as linhas com base em se elas atendem ou não a uma certa condição e exibir apenas aquelas que atendem.

A sintaxe correspondente é df.loc[conditional_expression], sendo conditional_expression uma declaração sobre os valores permitidos em uma coluna específica.

Para colunas com dados não numéricos (como Nome ou País), a declaração só pode usar o operador de igualdade ou desigualdade, pois não há ordem entre os valores. Poderíamos, por exemplo, retornar todas as linhas de clientes que não são da Ásia:

df.loc[df['Region'] != 'Asia']

ID do Cliente

Nome

País

Região

Idade

C123

João da Silva

Estados Unidos

América do Norte

67

C234

Petra Müller

Alemanha

Europa

51

C456

Maria Gonzalez

México

América do Norte

26

Selecionando uma única coluna usando .loc

Para selecionar colunas, precisamos especificar o argumento column_indexer, que vem após o argumento row_indexer. Se quisermos apenas especificar o column_indexer, precisamos de alguma forma indicar que queremos retornar todas as linhas e filtrar apenas nas colunas. Vamos ver como podemos fazer isso!

Selecionar uma única coluna pode ser feito especificando o column_indexer com o rótulo da respectiva coluna. Para recuperar todas as linhas, precisamos especificar o row_indexer com dois pontos simples. Chegamos a uma sintaxe que se parece com isto: df.loc[:, 'column_name'].

Vamos exibir o Nome de cada cliente:

df.loc[:, 'Name']

ID do Cliente

Nome

C123

John Doe

C234

Petra Müller

C345

Ali Khan

C456

Maria Gonzalez

C567

David Lee

Selecionando várias colunas usando .loc

Semelhante à seleção de várias linhas, precisamos passar uma lista de rótulos de coluna se quisermos retornar várias colunas de um DataFrame que não necessariamente seguem uma após a outra em ordem: df.loc[:, [col_label_1, 'col_label_2']].

Supondo que quiséssemos adicionar a Idade de todos os clientes à nossa última saída, funcionaria assim:

df.loc[:, ['Name', 'Age']]

ID do Cliente

Nome

Idade

C123

John Doe

67

C234

Petra Müller

51

C345

Ali Khan

19

C456

Maria Gonzalez

26

C567

David Lee

40

Selecionando uma fatia de colunas usando .loc

Usar dois pontos entre os rótulos de duas colunas selecionará todas as colunas na faixa de ordem entre as duas colunas especificadas. Isso inclui a coluna final, o que significa que a coluna chamada col_end também será selecionada na sintaxe padrão, que é a seguinte: df.loc[:, 'col_start':'col_end'].

Se estivermos interessados no Nome, País e Região de nossos clientes, nossa linha de código poderia ser:

df.loc[:, 'Name':'Region']

ID do Cliente

Nome

País

Região

C123

John Doe

Estados Unidos

América do Norte

C234

Petra Müller

Alemanha

Europa

C345

Ali Khan

Paquistão

Ásia

C456

Maria Gonzalez

México

América do Norte

C567

David Lee

China

Ásia

Seleção combinada de linha e coluna usando .loc

Também é possível especificar tanto o row_indexer quanto o column_indexer. Isso pode ser usado para recuperar uma única peça de informação, ou seja, uma célula do DataFrame. Para fazer isso, especificamos uma linha e uma coluna usando a sintaxe df.loc['row_label', 'column_name'] .

O caso mais útil é retornar um sub-DataFrame que se concentra exatamente no conjunto de linhas e colunas de nosso interesse. É possível especificar ambos os indexadores como listas usando os colchetes, ou como uma fatia usando dois pontos, e até combiná-lo com uma expressão condicional para a seleção de linha.

Aqui está um exemplo de retorno do Name, Country e Region de cada cliente com um Age superior a 30:

df.loc[df['Age'] > 30, 'Name':'Region']

ID do Cliente

Nome

País

Região

C123

John Doe

Estados Unidos

América do Norte

C234

Petra Müller

Germany

Europe

C567

David Lee

China

Asia

Usando .iloc: Seleção por Posição Inteira

.iloc seleciona por posição em vez de rótulo. Esta é a sintaxe padrão para usar .iloc: df.iloc[indice_linha, indice_coluna]. Existem duas coisas especiais para observar:

  • Contagem iniciando em 0: A primeira linha e coluna têm o índice 0, a segunda tem índice 1, etc.
  • Exclusividade do valor final do intervalo: Ao usar um intervalo, a linha ou coluna especificada após os dois pontos não está incluída na seleção.

Selecionando uma única linha usando .iloc

Uma única linha pode ser selecionada usando o número inteiro que representa o índice da linha como o indice_linha. Não precisamos de aspas, já que estamos inserindo um número inteiro e não uma string de rótulo como fizemos com .loc. Para retornar a primeira linha de um DataFrame chamado df, insira df.iloc[0].

Em nosso exemplo de DataFrame, esta linha de código retorna as informações de John Doe:

df.iloc[0]

C123

 

Nome

John Doe

País

Estados Unidos

Região

América do Norte

Idade

67

Selecionando várias linhas usando .iloc

Selecionar várias linhas funciona em .iloc como em .loc—nós inserimos os índices das linhas em uma lista com colchetes. A sintaxe é assim: df.iloc[[0, 3, 4]].

A saída respectiva em nossa tabela de clientes pode ser vista abaixo:

df.iloc[[0, 3, 4]]

ID do Cliente

Nome

País

Região

Idade

C123

John Doe

Estados Unidos

América do Norte

67

C456

Maria Gonzalez

México

América do Norte

26

C567

David Lee

China

Ásia

40

Selecionando um segmento de linhas usando .iloc

Para selecionar um segmento de linhas, usamos dois inteiros de índice de linha especificados separados por dois pontos. Agora, precisamos prestar atenção à exclusividade mencionada anteriormente. 

Podemos pegar a linha df.iloc[1:4] como exemplo para ilustrar este conceito. O número do índice 1 significa a segunda linha, então nosso segmento começa lá. O inteiro do índice 4 representa a quinta linha – mas como .iloc não é inclusivo para seleção de segmento, nossa saída incluirá todas as linhas até a última antes desta. Portanto, retornará a segunda, terceira e quarta linha. 

Vamos provar que a linha funciona como deveria:

df.iloc[1:4]

ID do Cliente

Nome

País

Região

Idade

C234

Petra Müller

Alemanha

Europa

51

C345

Ali Khan

Paquistão

Ásia

19

C456

Maria Gonzalez

México

América do Norte

26

Selecionar uma única coluna usando .iloc

A lógica de seleção de colunas usando .iloc segue o que aprendemos até agora. Vamos ver como funciona para colunas únicas, múltiplas colunas e fatias de colunas.

Assim como com .loc, é importante especificar o row_indexer antes de podermos prosseguir para o column_indexer. Para recuperar os valores da terceira coluna de df para cada linha, digitamos df.iloc[:, 2] .

Como Region é a terceira coluna no nosso DataFrame, ela será recuperada como consequência dessa linha de código:

df.iloc[:, 2]

ID do Cliente

Região

C123

América do Norte

C234

Europa

C345

Ásia

C456

América do Norte

C567

Ásia

Selecionando várias colunas usando .iloc

Para selecionar várias colunas que não são necessariamente subsequentes, podemos novamente inserir uma lista contendo inteiros como o column_indexer. A linha df.iloc[:, [0, 3]] retorna tanto a primeira quanto a quarta colunas.

No nosso caso, as informações exibidas são o Nome e a Idade de cada cliente:

df.iloc[:, [0, 3]]

ID do Cliente

Nome

Idade

C123

John Doe

67

C234

Petra Müller

51

C345

Ali Khan

19

C456

Maria Gonzalez

26

C567

David Lee

40

Selecionando uma fatia de colunas usando .iloc

Para a seleção de fatias usando .iloc, a lógica do column_indexer segue a do row_indexer. A coluna representada pelo inteiro após os dois pontos não está incluída na saída. Para recuperar a segunda e terceira colunas, a linha de código deve parecer com isso: df.iloc[:, 1:3].

Esta linha abaixo retorna todas as informações geográficas que temos sobre nossos clientes:

df.iloc[:, 1:3]

ID do Cliente

País

Região

C123

Estados Unidos

América do Norte

C234

Alemanha

Europa

C345

Pakistan

Ásia

C456

México

América do Norte

C567

China

Ásia

Seleção combinada de linha e coluna usando .iloc

Podemos juntar o que aprendemos sobre .iloc para combinar a seleção de linha e coluna. Novamente, é possível retornar tanto uma única célula quanto um sub-DataFrame. Para retornar a única célula na interseção da linha 3 e coluna 4, digitamos df.iloc[2, 3].

Assim como com .loc, podemos especificar ambos os índices como listas usando colchetes, ou como um intervalo usando dois pontos. Se quisermos selecionar linhas usando expressões condicionais, isso é tecnicamente possível com .iloc também, mas não é recomendado. Usar os nomes de rótulo e .loc é geralmente muito mais intuitivo e menos propenso a erros.

Este último exemplo exibe País, Região e Idade para a primeira, segunda e quinta linha em nosso DataFrame:

df.iloc[[0,1,4], 1:4]

ID do Cliente

País

Região

Idade

C123

Estados Unidos

América do Norte

67

C234

Alemanha

Europa

51

C567

China

Ásia

40

.iloc vs .loc: Quando Usar Qual

Em geral, há uma regra simples a seguir onde a escolha do método depende do seu conhecimento do DataFrame:

  • Use .loc quando você conhece os rótulos (nomes) das linhas/colunas.
  • Use .iloc quando você conhece as posições inteiras das linhas/colunas.

Alguns cenários favorecem .loc ou .iloc por natureza. Por exemplo, iterar sobre linhas ou colunas é mais fácil e intuitivo usando inteiros do que rótulos. Como já mencionamos, filtrar linhas com base em condições nos valores das colunas é menos propenso a erros usando os nomes dos rótulos das colunas.

Cenários que favorecem .loc

Cenários que favorecem .iloc

Seu DataFrame tem nomes de índice/coluna significativos.

Você está iterando sobre linhas/colunas pela sua posição.

Você precisa filtrar com base em condições sobre os valores das colunas.

Os nomes de índice/coluna não são relevantes para a sua tarefa.

KeyError, NameError e Index Error com .loc e .iloc

Vamos dar uma olhada nos problemas possíveis. Um erro comum ao usar .loc é encontrar um KeyError. Este erro ocorre quando tentamos acessar um rótulo de linha ou coluna que não existe dentro do nosso DataFrame. Para evitar isso, sempre devemos garantir que os rótulos que estamos usando sejam precisos e que correspondam aos rótulos existentes no seu DataFrame e verificar se há erros de digitação.

Além disso, é importante sempre usar aspas para os rótulos especificados usando .loc. Esquecê-las retornará um NameError.

Um IndexError pode ocorrer ao usar .iloc se especificarmos uma posição inteira que está fora do intervalo válido dos índices do nosso DataFrame. Isso acontece quando o índice que você está tentando acessar não existe, seja porque está além do número de linhas ou colunas em seu DataFrame ou porque é um valor negativo. Para evitar esse erro, verifique as dimensões do seu DataFrame e use valores de índice apropriados dentro do intervalo válido.

Conclusão

Espero que este blog tenha sido útil e que a distinção entre .loc e .iloc esteja clara agora. Para saber mais, aqui estão alguns bons próximos passos:

Source:
https://www.datacamp.com/tutorial/loc-vs-iloc