Eu tenho um Pandas DataFrame
, conforme definido aqui :
df = pd.DataFrame({'Name': ['Alice', 'Bob', 'Aritra'],
'Age': [25, 30, 35],
'Location': ['Seattle', 'New York', 'Kona']},
index=([10, 20, 30]))
No entanto, quando indexo this DataFrame
, não posso prever com precisão que tipo de objeto resultará da indexação:
# (1) str
df.iloc[0, df.columns.get_loc('Name')]
# (2) Series
df.iloc[0:1, df.columns.get_loc('Name')]
# (3) Series
df.iloc[0:2, df.columns.get_loc('Name')]
# (4) DataFrame
df.iloc[0:2, df.columns.get_loc('Name'):df.columns.get_loc('Age')]
# (5) Series
df.iloc[0, df.columns.get_loc('Name'):df.columns.get_loc('Location')]
# (6) DataFrame
df.iloc[0:1, df.columns.get_loc('Name'):df.columns.get_loc('Location')]
Observe que cada um dos pares acima contém os mesmos dados . (por exemplo, (2)
é uma série que contém uma única string, (4)
é um DataFrame que contém uma única coluna, etc.)
Por que eles produzem diferentes tipos de objetos? Como posso prever que tipo de objeto será gerado?
Dados os dados, parece que a regra é baseada em quantas fatias (dois pontos) você tem no índice:
- 0 fatias (
(1)
): valor escalar - 1 fatia (
(2)
,(3)
,(5)
):Series
- 2 fatias (
(4)
,(6)
):DataFrame
No entanto, não tenho certeza se isso é sempre verdade e, mesmo que seja sempre verdade, quero saber o mecanismo subjacente que explica por que isso acontece.
Passei um tempo olhando a documentação de indexação , mas ela não parece descrever esse comportamento com clareza. A documentação da iloc
função também não descreve os tipos de retorno.
Também estou interessado na mesma pergunta forloc
em vez de iloc
, mas, como loc
é inclusive , os resultados não são tão desconcertantes. (Ou seja, você não pode obter pares de índices com tipos diferentes nos quais os índices deveriam extrair exatamente os mesmos dados.)
Você entendeu a ideia geral. Para simplificar, o que importa não é o número de itens, mas o tipo de indexador.
Você pode indexar como 0D (com um escalar), vamos considerar o índice por enquanto:
ou 1D (com uma fatia ou iterável):
Então a regra é simples, considere ambos os eixos, se ambos forem 0D você obtém um escalar (aqui uma string), se ambos forem 1D você obtém um DataFrame, caso contrário, uma Série:
Alguns exemplos para ilustrar isso: