Alguém pode explicar como esses três métodos de fatiar são diferentes?
Eu já vi os documentos e essas respostas , mas ainda me encontro incapaz de explicar como os três são diferentes. Para mim, eles parecem intercambiáveis em grande parte, porque estão nos níveis mais baixos de fatiamento.
Por exemplo, digamos que queremos obter as cinco primeiras linhas de a DataFrame
. Como é que todos esses três funcionam?
df.loc[:5]
df.ix[:5]
df.iloc[:5]
Alguém pode apresentar três casos em que a distinção de usos é mais clara?
Respostas:
Nota: no pandas versão 0.20.0 e superior,
ix
está obsoleto e o uso deloc
eiloc
é incentivado. Deixei as partes desta resposta que descrevemix
intactas como uma referência para usuários de versões anteriores do pandas. Exemplos foram adicionados abaixo, mostrando alternativas paraix
.Primeiro, aqui está uma recapitulação dos três métodos:
loc
obtém linhas (ou colunas) com rótulos específicos do índice.iloc
obtém linhas (ou colunas) em posições específicas no índice (portanto, são necessários números inteiros).ix
geralmente tenta se comportar como,loc
mas volta a se comportar comoiloc
se um rótulo não estivesse presente no índice.É importante observar algumas sutilezas que podem ser
ix
um pouco complicadas de usar:se o índice for do tipo inteiro,
ix
usará apenas a indexação baseada em rótulo e não voltará à indexação baseada em posição. Se o rótulo não estiver no índice, um erro será gerado.se o índice não contiver apenas números inteiros, um número inteiro
ix
usará imediatamente a indexação baseada em posição em vez da indexação baseada em rótulo. Se, no entanto,ix
receber outro tipo (por exemplo, uma string), ele poderá usar a indexação baseada em rótulo.Para ilustrar as diferenças entre os três métodos, considere a seguinte série:
Veremos fatiar com o valor inteiro
3
.Nesse caso,
s.iloc[:3]
retorna as 3 primeiras linhas (já que trata 3 como uma posição) es.loc[:3]
retorna as 8 primeiras linhas (já que trata 3 como um rótulo):Aviso
s.ix[:3]
retorna a mesma série ques.loc[:3]
uma vez que procura primeiro o rótulo em vez de trabalhar na posição (e o índice paras
é do tipo inteiro).E se tentarmos com um rótulo inteiro que não esteja no índice (por exemplo,
6
)?Aqui
s.iloc[:6]
retorna as 6 primeiras linhas da série conforme o esperado. No entanto,s.loc[:6]
gera um KeyError, pois6
não está no índice.De acordo com as sutilezas mencionadas acima,
s.ix[:6]
agora gera um KeyError porque ele tenta funcionar comoloc
mas não consegue encontrar um6
no índice. Como nosso índice é do tipo inteiroix
ele não volta a se comportar comoiloc
.Se, no entanto, nosso índice fosse do tipo misto, dado que um número inteiro
ix
se comportaria comoiloc
imediatamente, em vez de gerar um KeyError:Lembre-se de que
ix
ainda é possível aceitar números não inteiros e se comportar da seguinte maneiraloc
:Como orientação geral, se você estiver indexando apenas usando rótulos ou indexando apenas com posições inteiras, use
loc
ouiloc
evite resultados inesperados - tente não usarix
.Combinando indexação baseada em posição e baseada em rótulo
Às vezes, com um DataFrame, você desejará combinar métodos de indexação de rótulo e de posição para as linhas e colunas.
Por exemplo, considere o seguinte DataFrame. Qual a melhor forma de dividir as linhas até e incluindo 'c' e pegar as quatro primeiras colunas?
Nas versões anteriores do pandas (antes da versão 0.20.0),
ix
você pode fazer isso de maneira bem organizada - podemos dividir as linhas por rótulo e as colunas por posição (observe que, para as colunas,ix
o padrão será o faturamento baseado em posição, pois4
não é um nome de coluna ):Nas versões posteriores dos pandas, podemos alcançar esse resultado usando
iloc
e com a ajuda de outro método:get_loc()
é um método de índice que significa "obter a posição do rótulo neste índice". Observe que, desde o corte comiloc
é exclusivo de seu ponto de extremidade, devemos adicionar 1 a esse valor se quisermos a linha 'c' também.Existem outros exemplos na documentação dos pandas aqui .
fonte
loc
,iloc
eix
ainda pode acionar o aviso se eles são encadeados. O uso do exemplo DataFrame nos documentos vinculadosdfmi.loc[:, 'one'].loc[:, 'second']
aciona o aviso da mesma maneiradfmi['one']['second']
que uma cópia dos dados (em vez de uma exibição) pode ser retornada pela primeira operação de indexação.df.ix[date, 'Cash']
?loc
ouix
devem funcionar nesse caso. Por exemplo,df.loc['2016-04-29', 'Cash']
retornará todos os índices de linha com essa data específica na coluna 'Caixa'. (Você pode ser o mais específico possível ao recuperar índices com seqüências de caracteres, por exemplo'2016-01'
, selecionará todas as datas em janeiro de 2016, `` 2016-01-02 11 'selecionará as datas em 2 de janeiro de 2016 com o horário 11: ??: ?? .)iloc
funciona com base no posicionamento inteiro. Portanto, não importa quais sejam seus rótulos de linha, você sempre pode, por exemplo, obter a primeira linha fazendoou as últimas cinco linhas, fazendo
Você também pode usá-lo nas colunas. Isso recupera a terceira coluna:
Você pode combiná-los para obter interseções de linhas e colunas:
Por outro lado,
.loc
use índices nomeados. Vamos configurar um quadro de dados com seqüências de caracteres como rótulos de linha e coluna:Então podemos obter a primeira linha por
e as segundas duas linhas da
'date'
coluna pore assim por diante. Agora, vale a pena ressaltar que os índices padrão de linha e coluna para a
DataFrame
são números inteiros de 0 e, nesse caso,iloc
eloc
funcionariam da mesma maneira. É por isso que seus três exemplos são equivalentes. Se você tivesse um índice não numérico, como seqüências de caracteres ou data / hora, issodf.loc[:5]
geraria um erro.Além disso, você pode fazer a recuperação da coluna apenas usando os quadros de dados
__getitem__
:Agora, suponha que você queira misturar a posição e a indexação nomeada, ou seja, indexar usando nomes em linhas e posições em colunas (para esclarecer, quero dizer, selecione em nosso quadro de dados, em vez de criar um quadro de dados com seqüências de caracteres no índice de linha e números inteiros em o índice da coluna). É aqui que
.ix
entra:Também acho que vale a pena mencionar que você também pode passar vetores booleanos para o
loc
método. Por exemplo:Retornará a primeira e a terceira linhas de
df
. Isso é equivalente adf[b]
seleção, mas também pode ser usado para atribuir via vetores booleanos:fonte
df.loc[:, :]
. Pode ser usado para reatribuir os valores do todoDataFrame
ou criar uma visualização dele.Na minha opinião, a resposta aceita é confusa, pois usa um DataFrame com apenas valores ausentes. Também não gosto do termo baseado em posição
.iloc
e prefiro local inteiro , pois é muito mais descritivo e exatamente o que.iloc
significa. A palavra-chave é INTEGER -.iloc
precisa de INTEGERS.Veja minha série de blogs extremamente detalhada sobre seleção de subconjuntos para mais
.ix está obsoleto e ambíguo e nunca deve ser usado
Como
.ix
está obsoleto, focaremos apenas nas diferenças entre.loc
e.iloc
.Antes de falarmos sobre as diferenças, é importante entender que os DataFrames têm rótulos que ajudam a identificar cada coluna e cada índice. Vamos dar uma olhada em um exemplo de DataFrame:
Todas as palavras em negrito são os rótulos. As etiquetas,
age
,color
,food
,height
,score
estate
são usados para as colunas . Os outros rótulos,Jane
,Nick
,Aaron
,Penelope
,Dean
,Christina
,Cornelia
são usados para o índice .As principais maneiras de selecionar linhas específicas em um DataFrame são com os indexadores
.loc
e.iloc
. Cada um desses indexadores também pode ser usado para selecionar colunas simultaneamente, mas é mais fácil focar apenas nas linhas por enquanto. Além disso, cada um dos indexadores usa um conjunto de colchetes que seguem imediatamente seu nome para fazer suas seleções..loc seleciona dados apenas por rótulos
Primeiro falaremos sobre o
.loc
indexador, que seleciona apenas os dados pelos rótulos do índice ou da coluna. Em nosso exemplo DataFrame, fornecemos nomes significativos como valores para o índice. Muitos DataFrames não terão nomes significativos e, em vez disso, usarão como padrão apenas os números inteiros de 0 a n-1, onde n é o comprimento do DataFrame.Existem três entradas diferentes que você pode usar para
.loc
Selecionando uma única linha com .loc com uma sequência
Para selecionar uma única linha de dados, coloque o rótulo do índice dentro dos colchetes a seguir
.loc
.Isso retorna a linha de dados como uma série
Selecionando várias linhas com .loc com uma lista de cadeias
Isso retorna um DataFrame com as linhas na ordem especificada na lista:
Selecionando várias linhas com .loc com notação de fatia
A notação de fatia é definida pelos valores de início, parada e etapa. Ao fatiar por etiqueta, os pandas incluem o valor de parada no retorno. As seguintes fatias de Aaron a Dean, inclusive. Seu tamanho da etapa não é definido explicitamente, mas o padrão é 1.
Fatias complexas podem ser obtidas da mesma maneira que as listas Python.
.iloc seleciona dados apenas por localização inteira
Vamos agora voltar para
.iloc
. Cada linha e coluna de dados em um DataFrame tem um local inteiro que o define. Isso é um acréscimo ao rótulo que é exibido visualmente na saída . O local inteiro é simplesmente o número de linhas / colunas da parte superior / esquerda começando em 0.Existem três entradas diferentes que você pode usar para
.iloc
Selecionando uma única linha com .iloc com um número inteiro
Isso retorna a 5ª linha (local inteiro 4) como uma Série
Selecionando várias linhas com .iloc com uma lista de números inteiros
Isso retorna um DataFrame da terceira e da segunda à última linhas:
Selecionando várias linhas com .iloc com notação de fatia
Seleção simultânea de linhas e colunas com .loc e .iloc
Uma excelente capacidade de ambos
.loc/.iloc
é a capacidade de selecionar linhas e colunas simultaneamente. Nos exemplos acima, todas as colunas foram retornadas de cada seleção. Podemos escolher colunas com os mesmos tipos de entradas que fazemos para linhas. Simplesmente precisamos separar a seleção de linha e coluna com uma vírgula .Por exemplo, podemos selecionar as linhas Jane e Dean com apenas as colunas altura, pontuação e estado da seguinte maneira:
Isso usa uma lista de rótulos para as linhas e notação de fatia para as colunas
Naturalmente, podemos realizar operações semelhantes
.iloc
usando apenas números inteiros.Seleção simultânea com rótulos e localização de número inteiro
.ix
foi usado para fazer seleções simultaneamente com rótulos e local inteiro, o que foi útil, mas às vezes confuso e ambíguo e, felizmente, foi preterido. No caso de você precisar fazer uma seleção com uma mistura de rótulos e locais inteiros, será necessário fazer os rótulos de seleção ou locais inteiros.Por exemplo, se quisermos selecionar linhas
Nick
e,Cornelia
juntamente com as colunas 2 e 4, poderíamos usar.loc
convertendo os números inteiros em rótulos com o seguinte:Ou, alternativamente, converta os rótulos de índice em números inteiros com o
get_loc
método index.Seleção booleana
O indexador .loc também pode fazer a seleção booleana. Por exemplo, se estivermos interessados em encontrar todas as linhas com idade acima de 30 e retornar apenas as colunas
food
escore
, podemos fazer o seguinte:Você pode replicar isso com,
.iloc
mas não pode transmitir uma série booleana. Você deve converter a série booleana em uma matriz numpy como esta:Selecionando todas as linhas
É possível usar
.loc/.iloc
apenas para seleção de coluna. Você pode selecionar todas as linhas usando dois pontos como este:O operador de indexação
[]
, também pode selecionar linhas e colunas, mas não simultaneamente.A maioria das pessoas conhece o objetivo principal do operador de indexação DataFrame, que é selecionar colunas. Uma cadeia de caracteres seleciona uma única coluna como uma série e uma lista de cadeias seleciona várias colunas como um DataFrame.
O uso de uma lista seleciona várias colunas
O que as pessoas estão menos familiarizadas é que, quando a notação de fatia é usada, a seleção acontece por rótulos de linha ou por local inteiro. Isso é muito confuso e algo que quase nunca uso, mas funciona.
A explicitação de
.loc/.iloc
para selecionar linhas é altamente preferida. O operador de indexação sozinho não pode selecionar linhas e colunas simultaneamente.fonte