Counting elements from one matrix, storing information in another

Asked

Viewed 709 times

1

Hello, I’m a beginner in python and I’m doing an exercise that consists in reading all the numbers of a matrix and adding in another matrix the numbers existing in the previous one and how often they appear. Consequently, the matrix 2 will have two lines, one containing the numbers, and the second how many times they appear. For example, if there is a number 10 and it appears 3 times, the second matrix will have in the first row the number 10, and in the second the number 3, the two in the same column.

NOTE: Consider the first matrix as any already declared.

...

matriz2=[]
linha1 = []
linha2 = []
qntde=0
linha1.append(0)
for l in range(numerodelinhas):
    for c in range(numerodecolunas):
        qntde = 0
        if(linha1.count(matriz[l][c])==0):
            if(l==0 and c == 0):
                linha1[0]=matriz[0][0]
            if(l != 0 or c != 0):
                linha1.append(matriz[l][c])
            for n in range(numerodelinhas):
                qntde = qntde + matriz[n].count(matriz[l][c])
            linha2.append(qntde)

matriz2.append(linha1)
matriz2.append(linha2)
cm2=0
for n in matriz2[0]:
    print (matriz2[0][cm2]," - ",matriz2[1][cm2])
    cm2+=1

The code worked, but I don’t like it at all. There would be a way to make it dry?

2 answers

1

You can take advantage of the class Collections. Counter, who receives a iterable or mapping and count the elements. The only adjustment is to turn the matrix into a list, but this is easily solved with the method itertools.chain.().

Follow an example of use:

from itertools import chain
from collections import Counter

# Matrix 4x4 apenas para exemplo
matriz = [
    [2, 4, 6, 8],
    [1, 2, 3, 5],
    [1, 1, 10, 20],
    [1, 2, 4, 7],
]

contador = Counter(chain.from_iterable(matriz))

# printa o objeto Counter, sendo as chaves o elemento
# contado e os valores quantas vezes eles aparecem na matriz
print(contador)

Output:

Counter({
    1: 4,
    2: 3,
    4: 2,
    6: 1,
    8: 1,
    3: 1,
    5: 1,
    10: 1,
    20: 1,
    7: 1
})

Repl.it

Edit: chain(*matriz) changed to chain.from_iterable(matriz) to keep the matrix loading Lazy. (tip: @nosklo)

  • In this case it makes no difference but usually it is better to use the chain.from_iterable: Counter(chain.from_iterable(matriz))

  • True @nosklo, I used unpacking for practicality, but in a real case it might not be performative. I will edit the answer, thank you.

0

There is a much easier way to deal with arrays and arrays in python, which is to use a library called numpy. Example:

In [1]: import numpy as np

# matriz1 gerada aleatoriamente de números de 0 a 5 com tamanho 3x3
In [2]: matriz1 = np.random.randint(0, 5, size=(3,3))

In [3]: matriz1
Out[3]: 
array([[1, 2, 4],
       [3, 1, 1],
       [2, 4, 4]])

# retorna os elementos únicos e o número de vezes em que cada um aparece
In [4]: elementos, contagem = np.unique(matriz1, return_counts=True)


# empilha os dois arrays de forma vertical, elementos em cima e contagem embaixo
In [5]: matriz2 = np.vstack([elementos, contagem])

In [6]: matriz2
Out[6]: 
array([[1, 2, 3, 4],
       [3, 2, 1, 3]])

For more information and documentation: http://www.numpy.org. Numpy is the base library for those who work in machine learning and data science. There are several tutorials available, worth checking out.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.