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

Dúvida em seleção com arrays

Olá pessoal, apenas uma dúvida no vídeo de seleção com arrays que ainda não ficou muito claro pra mim. No vídeo foi explicado por exemplo que para selecionar linhas e colunas pode ser feito do seguinte modo:

dados[1, 2]

ou

dados[1][2]

que geram o mesmo resultado, sendo que o primeiro item seleciona a linha e o segundo a coluna em ambos.

No entanto já mais ao final do vídeo ele explica a seleção de uma nova maneira, inclusive para cálculo dentro dos dados e aí que vem a dúvida, ele fez a seleção da seguinte maneira:

dados[:, 1:3][0] ...

ou seja, eu quero apenas entender a parte da seleção. Uma vez que lá em cima o primeiro item serviu para selecionar linha e o segundo a coluna, aqui surge o terceiro item que vem como segundo colchete, que seguindo uma lógica selecionaria a coluna também, mas aí ele seleciona a linha. Sempre será assim quando trabalhar dessa forma, ele vai acessar a linha ao invés da coluna?

11 respostas

Olá Fagner, tudo bem com você?

Em listas, utilizando python, seguindo o exemplo que você deu

dados[1, 2]

é uma lista e os componentes dela são chamados de índices. A lista "dados" do seu exemplo, possuí dois elementos. Sabendo que os índices são iniciados por "0" para acessar o item "1" da sua lista, é necessário chamar o elemento "0" e para acessar o item "2" é necessário chamar o elemento "1". Caso fique mais fácil para visualizar, pode utilizar letras no seu treino, no lugar de números:

dados[a,b]

o processo de seleção é o mesmo. Quando você menciona linha e coluna, trata-se de matrizes(tabelas), então nesse caso existe linha e coluna chamadas de arrays. Até aí blz? Então, um array ele não deixa de ser uma lista, pois, cada elemento do array pode ser um composto de outros elementos(lista) e serem chamados pelo índice "0" ou "1" como citamos. Olha esse exemplo de criação de array:

In [3]: a = np.zeros((5,5), dtype=np.float64)

In [4]: a[1:4, 1:4] = 1

In [5]: a
Out[5]: 
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  1.,  1.,  0.],
       [ 0.,  1.,  1.,  1.,  0.],
       [ 0.,  1.,  1.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

Fica fácil de ler e visualizar o que foi feito, primeiro é definido um array de zeros "0", então é determinado que os intervalos 1:4 tanto nas linhas quanto nas colunas serão substituídos por "1" e ao imprimir o resultado foi o visto acima.

Ficou mais claro? Ahh atente para os array que são compostos por "( )" e então as listas "[ ]" dentro . Espero ter ajudado, caso sua dúvida tenha sido resolvida, marca o Post como encerrado =) ou me pergunte novamente se ainda existir alguma dúvida.

Obrigado

Victor Gonzalez

Olá Victor, blz. Essa parte da sua explanação eu já enendi, mas minha dúvida ainda permanece. A grande questão é a seleção da nova maneira que ele faz no vídeo que eu não entendi muito bem. Dado que exatamente como ele fez:

dados[1, 2]
:1990
dados[1][2]
:1990

Ambos geram o mesmo resultado, ok?

Agora, no final ele faz uma seleção inclusive para fazer um cálculo que nem vou entrar no mérito aqui, mas o que quero mesmo entender é a questão da seleção em si que trouxe um resultado diferente da lógica que não entendi:

dados[:, 1:3][0]
:array([5712., 37123.])

Ou seja, dado que nos dois primeiros casos de seleção ele trouxe o mesmo valor sendo que se colocando o segundo colchete ele seleciona a coluna, nesse caso ele selecionou a linha... Daí vem a pergunta, sempre será assim quando trabalhar dessa forma, ele vai acessar a linha ao invés da coluna? Pois o primeiro item do primeiro colchete acessou a linha, o segundo item primeiro colchete acessou a coluna, e o primeiro item do segundo colchete acessou a linha ao invés de acessar a coluna como no primeiro exemplo de cima que o segundo colchete acessou a coluna e produziu o mesmo resultado. Conseguiu entender? Essa é minha dúvida.

Oi Fagner eu entendi sim sua dúvida. Peguei o arquivo usado na aula e trouxe para cá as informações das quais você está com dúvida.

dados
array([[44410.,  5712., 37123.,     0., 25757.],
       [ 2003.,  1991.,  1990.,  2019.,  2006.]])
dados[:, 1:3]
array([[ 5712., 37123.],
       [ 1991.,  1990.]])
dados[:, 1:3][0] / (2019 - dados[:, 1:3][1])
array([ 204.        , 1280.10344828])

Então a parte que "dados" é um array, você entendeu? Ou seja, dados = ([[44410., 5712., 37123., 0., 25757.], [ 2003., 1991., 1990., 2019., 2006.]]) a isso tudo, porém você observa que são duas listas? A primeira formada aqui: "[44410., 5712., 37123., 0., 25757.]" e aí separa por vírgula e a segunda aqui: "[ 2003., 1991., 1990., 2019., 2006.]"

na operação de seleção "dados [:, 1:3]" o que o professor faz é selecionar o elemento referente ao índice "1" e "2" na primeira lista, ou seja, "5712" e "37123" e na segunda lista a mesma seleção de índice, perceba a " , " onde ele puxa o índice "1" que é "1991" e o índice "2" que é "1990". Veja alguns exemplos usando seleção para ver se fica mais claro:

"O operador [a:b] possui o comprimento de a (inclusive) até b(exclusive):"

p = "python"
p[0:0] # ''
p[0:1] # 'p'
p[1:2] # 'y'
p[2:3] # 't'
p[3:4] # 'h'
p[4:5] # 'o'
p[5:6] # 'n'
p[6:6] # ''

O operador [:b] possui o comprimento até b (exclusive)":

p = "python"
p[:1] # 'p'
p[:2] # 'py'
p[:3] # 'pyt'
p[:4] # 'pyth'
p[:5] # 'pytho'
p[:6] # 'python'

"O operador [:] representa o total da lista (ou string).

E há ainda o operador [a:b:n] que representa de n em n itens."

O operador [a:] possui o comprimento a partir de a(inclusive):

p = "python"
p[:]  # 'python'
p[1:] # 'ython'
p[2:] # 'thon'
p[3:] # 'hon'
p[4:] # 'on'
p[5:] # 'n'
p[6:] # ''

Abre um note no colaboratory e escolhe uma palavra para ir brincando com as seleções, essa parte é meio complicadinha mesmo de entender. Espero que agora tenha ficado mais claro a minha explicação.

Obrigado =)

Victor Gonzalez

Olá Victor, blz. Essa parte aí eu já entendi muito bem no curso, ficou bem clara, ficou bem clara também a diferença entre lista e arrays do numpay, e a manipulação delas também ficou bem entendida. Só o que ficou foi essa parte da seleção mesmo.

Vou tentar pegar um exemplo mais específio ainda pra te explicar minha dúvida:

Se vc colocar

dados[1, 2]
:1990

Se vc colocar

dados[1][2]
:1990

Vai gerar o mesmo resultado, ou seja o segundo colchete [2] selecionou a coluna correto?

Agora se vc colocar

dados[1, 1:2][0]
:1991

Ou seja esse colchete [0] está selecionando a linha, que na situação normal anterior de cima em dados[1][2] o [2] selecionou a coluna, correto? Por que nesse caso de baixo em dados[1, 1:2][0] o [0] selecionou a linha e não a coluna? conseguiu entender? Outra questão também é que se vc colocar apenas

dados[1, 2][0]

Ele dá erro, parece que ele sempre espera uma seleção de coluna por ":"

Se vc também tentar acessar qualquer coluna como se fosse coluna mesmo, colocando 2, 3, 4 ou 5, ele dá erro como se tivesse estourado ou dado excesso. ou seja não é mais coluna entende. Parece que é linha e as vezes parece que não é bem linha que ele acessa.

Enfim, é isso que quero entender.

Olá Fagner,

Acho que o detalhe está no retorno de cada item, o acesso não é exatamente por linha e coluna e sim por índice. Fazendo apenas dados[1] vamos receber um array como retorno, assim já colocamos o segundo colchete para acessar esse array retornado:

dados[1][2]

# É o mesmo que:

array = dados[1]
array[2]

Esse acesso direto retorna o item do índice, não importa o tipo, pode retornar um número, um texto, uma lista, etc... Como no caso temos arrays dentro do array, recebemos um array de retorno com o dados[1], assim podemos adicionar o segundo par de colchetes para acessar dentro do array retornado.

O acesso utilizando a vírgula é um "atalho" para o que foi descrito acima, sendo dados[1][2] igual a dados[1, 2]


Já utilizando o fatiamento, colchetes com o :, o retorno vai ser sempre uma lista com os itens definidos. Então fazendo dados[1:3] vamos receber uma lista com os valores dos índices 1 e 2, e fazendo dados[1:2] vamos receber uma lista com um único valor, o do índice 1. O importante é que o retorno é sempre uma lista.


Então resumindo tudo isso acima temos que dados[1][1], dados[1, 1] e dados[1, 1:2] selecionam o mesmo item, mas em formatos diferentes.

Então voltando ao seu exemplo e quebrando em partes:

dados[1, 1:2][0]
  • Em [1, 1:2] o 1 seleciona o array de anos: [2003, 1991, 1990, 2019, 2006]
  • O 1:2 seleciona um lista desse array de anos: [1991]
  • E por fim o [0] pega o primeiro item da lista retornada acima: 1991

E no caso do dados[1, 2][0] retornar um erro, é porque o [1, 2] já acessa o item diretamente:

# Retorna uma lista
dados[1, 1:2]

# Retorna um número
dados[1, 2][0]

Muito obrigado pela ajuda Lucas! Excelente explicação =) e organização da resposta. Irei usar como base.

Olá Lucas, vlw pela resposta, chegou mais perto de sanar minha dúvida. Mas ainda está nebuloso essa parte na minha cabeça...

No vídeo ele explica o acesso como linha e coluna e não como índice, ele fala em índice apenas quando explica a parte de fatiamenteo que entendi bem, já a parte de seleção ele fala em linha e coluna sendo o primeiro item para acessar as linhas e o segundo para acessar as colunas, mas vou tentar entender como vc explicou. Mas ainda assim não entendi muito bem.

Vamos lá, no vídeo temos a explicação da tabela de dados como:

   0    1   2    3   4

[44410, 5712, 37123, 0 , 25757]<- 0

[2003, 1991, 1990, 2019, 2006]<- 1

Você explicou que o segundo colchete acessa dentro de um array retornado, sendo a vírgula um atalho para esse segundo colchete colocado, gerando o mesmo resultado. Então esse segundo colchete sempre irá retornar um array de um outro array é isso? E porque então temos a sensação então de ele estar selecionado a "coluna" ao determinar o item do segundo colchete? Como por exemplo:

dados[:][4]
:25757, 2006

ou seja, ele foi em todas as "linhas" e acessou a "coluna 4" e trouxe os valores 25757 e 2006. Agora tentando enteder pela sua lógica ainda fiquei perdido, ele pegou o índice passado que foi o : e selecionou toda aquela lista daquele ídice, no caso [44410, 5712, 37123, 0, 25757] e [2003, 1991, 1990, 2019, 2006], daí daquele índice ele pegou o de equivalente ao ídice 4 da lista, e de todas as outras que aparecessem correto?

Agora se eu adicionar mais um colchete para acessar mais algo nisso que ainda ficou um pouco confuso ainda. No caso se eu colocar um [0], na minha cabeça ele vai tentar acessar a "coluna" 0 e tentar puxar algum valor que esteja lá, no caso, 44410 ou 2003, mas não é isso que ocorre... ele vai tentar acessar como?

Quando fiz

dados[:][4][0]
:25757
solução!

Não tem nenhum problema em considerar como linha e coluna, mas isso só é possível no caso de um array com arrays dentro, a linha é o índice do array principal e a coluna é o índice do array interno da linha selecionada.

Quando você fez dados[:][4] qual era o valor de dados?

Para ajudar na dúvida você pode compartilhar o seu código completo? O formato do array e do conteúdo do array importam muito, e acredito que estamos utilizando dados diferentes.

Olá Lucas blz.

Quando eu fiz dados[:][4] o resultado foi o que coloquei: 25757, 2006.

Os dados que estou utilizando é o mesmo da aula...

O formato do array de dados foi esse que passei aí em cima usando até a marcação das colunas e linhas numeradas, que é o mesmo usado na aula...

Mas com sua explicação de agora me caiu a ficha totalmente, obrigado!!! Quando você explicou que a linha é o índice do array principal e a coluna é o índice do array interno da linha selecionada e creio que assim sucessivamente sempre...

Quando fiz dados[:][4][0] ele retornou 25757 por ser conforme sua explicação dos dois itens da lista de dados[:][4] o mais interno dessa lista, tanto que se eu fizer dados[:][4][1] ele retorna agora 2006 que é o mais interno relacionado ao índice passado, no caso a "coluna" e não a coluna da matriz inicial que eu tava pensando que ele pegaria. Agora fez sentido pra mim.

a linha é o índice do array principal e a coluna é o índice do array interno da linha selecionada e creio que assim sucessivamente sempre

Isso mesmo, olhar como linha e coluna é mais útil no cenário específico de um array de arrays (chamado de 2d-array no python), na dúvida recomendo olhar como índices de cada nível.

Lembrando que dados[:] vai retornar todos os itens como o Victor explicou, assim dados[:] é igual a dados, e dados[:][4] é igual a dados[4].

Fico feliz em poder ter ajudado! Qualquer outra dúvida é só falar aqui ou abrir um novo tópico que a gente tenta ajudar.

Vlw, vou fechar por aqui então, muito grato...