Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Dúvida sobre pd.DataFrame(dados[['Tipo Agregado', 'Valor m2', 'Valor Bruto', 'Valor Bruto m2']])

Basicamente queria saber o motivo específico sobre ter dois colchetes "[[]]" para colocar dentro de dados em

dados([['Tipo Agregado', 'Valor m2', 'Valor Bruto', 'Valor Bruto m2']])

Testei apenas com um colchete dados(['Tipo Agregado', 'Valor m2', 'Valor Bruto', 'Valor Bruto m2'])

e então acusa um erro que eu li inteiro e ainda não entendi o porquê de ter que ser dois colchetes.

Erro:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
D:\anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
   3628             try:
-> 3629                 return self._engine.get_loc(casted_key)
   3630             except KeyError as err:

D:\anaconda3\lib\site-packages\pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()

D:\anaconda3\lib\site-packages\pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: ('Tipo Agregado', 'Valor m2', 'Valor Bruto', 'Valor Bruto m2')

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_25616\2569172126.py in <module>
----> 1 dados_aux = pd.DataFrame(dados['Tipo Agregado', 'Valor m2', 'Valor Bruto', 'Valor Bruto m2'])

D:\anaconda3\lib\site-packages\pandas\core\frame.py in __getitem__(self, key)
   3503             if self.columns.nlevels > 1:
   3504                 return self._getitem_multilevel(key)
-> 3505             indexer = self.columns.get_loc(key)
   3506             if is_integer(indexer):
   3507                 indexer = [indexer]

D:\anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
   3629                 return self._engine.get_loc(casted_key)
   3630             except KeyError as err:
-> 3631                 raise KeyError(key) from err
   3632             except TypeError:
   3633                 # If we have a listlike key, _check_indexing_error will raise

KeyError: ('Tipo Agregado', 'Valor m2', 'Valor Bruto', 'Valor Bruto m2')
4 respostas
solução!

Embora sejam dois colchetes "[[]]" eles possuem significados diferentes.

O colchete externo está chamando um método para "indexar", e esse método espera uma entrada que pode ser:

  • a) o nome de uma coluna; ou
  • b) uma lista de nomes de colunas. A opção "b" é exatamente o que o colchete esterno está fazendo: "criando uma lista".

Se você indexar apenas com o nome de uma coluna, por ex:

dados['Tipo Agregado']

Vai ter como resultado um objeto do tipo Series representando uma única coluna do seu DataFrame.

Já se indexar passando uma lista de nomes de colunas, assim:

minhas_colunas = ['Tipo Agregado', 'Valor m2', 'Valor Bruto', 'Valor Bruto m2']
dados[minhas_colunas]

# que é o mesmo que assim:
dados[['Tipo Agregado', 'Valor m2', 'Valor Bruto', 'Valor Bruto m2']]

Vai ter como resultado um objeto DataFrame com cada uma das colunas que escolheu.

Agora se passar mais de um nome de coluna sem estar em uma lista (ou seja, sem os colchetes internos), é como se o método entendesse que a junção de todos esses nomes é uma coluna só (afinal, ele não recebeu uma lista). Ele tenta achar uma coluna que corresponda a esse nome, não encontra e retorna erro de chave.

Olá, nesse caso, nâo é inadequado usar o termo "método", já que, no pandas, o método é expresso por parênteses?

Boa observação Rogério. Não só no pandas, mas para qualquer objeto definido em python, geralmente métodos são chamados com parêntesis. Ex:


df.shape     # acessa um *atributo* do DataFrame
df.head()    # executa um *método* do DataFrame

Porém, quando usamos um operador o que estamos fazendo implicitamente é chamar um método. Por exemplo, veja como o operador "+" tem um comportamento diferente de acordo com o tipo dos operandos:


1 + 3       # => 4      // adição de valores
[1] + [3]   # => [1, 3] // concatenação de listas

E onde está definido esse comportamento do operador "+"? Está definido em um método "__add__".

Esses métodos entre "__" são conhecidos no python como "magic methods". E no caso do operador de indexação "[]", o seu método correspondente é o __get_item__ e era a esse que eu me referi na resposta. Você pode observar na mensagem de erro do Felipe que o erro se dá passando pela utilização desse método (o penúltimo a ser chamado):


D:\anaconda3\lib\site-packages\pandas\core\frame.py in __getitem__(self, key)

Gente, eu tive que editar o post e corrigir porque faltaram os parênteses. São dois colchetes dentro de um parênteses. Essa era a dúvida. Por que não um colchete dentro do parênteses?