How to iterate through a matrix column in python

16,443

Solution 1

You have not specified what the datatype of your matrix is. If it is a list of lists, then there is no way to "get just one column", but the code still is similar (assuming that r and c are of type int):

I added the functionality to only count the cells adjacent to the cell in question (above, below, left and right; does NOT consider diagonals); this is done checking that the difference between indexes is not greater than 1.

count_in_row = 0
count_in_col = 0
value = matrix[r][c]

for j in range(len(matrix[r])):
    if abs(j - c) <= 1:             # only if it is adjacent
        if matrix[r][j] == value:
            count_in_row += 1
for i in range(len(matrix)):
    if abs(i - r) <= 1:             # only if it is adjacent
        if matrix[i][c] == value:
            count_in_col += 1

Or if following the way you started it (whole rows and columns, not only adjacent ones):

for col_val in matrix[r]:
    if col_val == value:
        count_in_row += 1
for row in matrix:
    if row[c] == value:
        count_in_col += 1

If you will be doind this for a lot of cells, then there are better ways to do that (even without numpy, but numpy is defenitively a very good option).

Solution 2

You can create a list for rows and cols and simply iterate over your matrix once while adding up the correct parts:

Create demodata:

import random

random.seed(42)

matrix = []
for n in range(10):
    matrix.append(random.choices([0,1],k=10))

print(*matrix,sep="\n")

Output:

[1, 0, 0, 0, 1, 1, 1, 0, 0, 0]
[0, 1, 0, 0, 1, 1, 0, 1, 1, 0]
[1, 1, 0, 0, 1, 0, 0, 0, 1, 1]
[1, 1, 1, 1, 0, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 1, 1, 1, 0, 1, 0, 0]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
[0, 1, 1, 0, 1, 0, 1, 0, 0, 0]
[1, 0, 1, 1, 0, 0, 1, 1, 0, 0]
[0, 1, 1, 0, 0, 0, 1, 1, 1, 1]

Count things:

rows =  []                   # empty list for rows - you can simply sum over each row
cols =  [0]*len(matrix[0])   # list of 0 that you can increment while iterating your matrix

for row in matrix:
    for c,col in enumerate(row):  # enumerate gives you the (index,value) tuple
        rows.append( sum(x for x in row) )    # simply sum over row
        cols[c] += col                        # adds either 0 or 1 to the col-index           

print("rows:",rows)
print("cols:",cols)

Output:

rows: [4, 5, 5, 9, 2, 4, 6, 4, 5, 6] # row 0 == 4, row 1 == 5, ...
cols: [6, 6, 5, 4, 6, 5, 5, 5, 5, 3] # same for cols

Less code but taking 2 full passes over your matrix using zip() to transpose the data:

rows =  [sum(r) for r in matrix]
cols =  [sum(c) for c in zip(*matrix)]

print("rows:",rows)
print("cols:",cols)

Output: (the same)

rows: [4, 5, 5, 9, 2, 4, 6, 4, 5, 6]  
cols: [6, 6, 5, 4, 6, 5, 5, 5, 5, 3]  

You would have to time it, but the overhead of two full iteration and the zipping might be still worth it, as the zip() way is inheritently more optimized then looping over a list. Tradeoff might only be worth it for / up to / up from certain matrix sizes ...

Solution 3

I will not solve that for you, but maybe hint in the right direction...

# assuming a list of lists of equal length
# without importing any modules

matrix = [
    [1, 0, 0, 0],
    [1, 1, 0, 0],
    [1, 1, 1, 0],
    [1, 1, 1, 1],
]

sum_rows = [sum(row) for row in matrix]
print(sum_rows)  # [1, 2, 3, 4]

sum_columns = [sum(row[i] for row in matrix) for i in range(len(matrix[0]))]
print(sum_columns)  # [4, 3, 2, 1]
Share:
16,443

Related videos on Youtube

Orbit09
Author by

Orbit09

Updated on June 04, 2022

Comments

  • Orbit09
    Orbit09 almost 2 years

    I have a matrix with the cell values only 0 or 1.

    I want to count how many ones or zeros are there in the same row or column to a given cell.

    For example, the value matrix[r][c] is 1, so I want to know how many ones are there in the same row. This code does that:

    count_in_row = 0
    value = matrix[r][c]
    for i in matrix[r]:
        if i == value:
            count_in_row += 1
    

    The for cycle iterates through the same row and counts all ones (cells with the same value).

    What if I want to do the same process with columns? Will I iterate through the whole matrix or it is possible through just one column?

    PS: I don't want to use numpy, transpose or zip; better with composite cycle.

    • Patrick Artner
      Patrick Artner over 5 years
      Why would you forgoe using numpy, transpose or zip? that sounds like artificial constraints put on you for some kind of task by a teacher/professor.
    • Orbit09
      Orbit09 over 5 years
      @PatrickArtner Yes, the professor told us to try finding the solution without importing any modules. I easily made up the row part, but columns are much more difficult :)
    • Ralf
      Ralf over 5 years
      @Orbit09 What type is your matrix (print(type(matrix)))? List of lists?
  • Orbit09
    Orbit09 over 5 years
    Thanks Ralf, this is exactly what I need! You guessed right, my matrix is a list of lists. One more question: what if I want to count only adjacent cells with the same number? Eg. my row is [1, 0, 1, 1, 1, 1, 0] and the fifth number is 1, so I want to count all ones that are adjacent to that fifth one until there is zero. So the result count should be 4.
  • Ralf
    Ralf over 5 years
    @Orbit09 I added the adjacency control, it simply assures that the difference between indixes is at most 1
  • Orbit09
    Orbit09 over 5 years
    Didn't you mean if abs(j - r) <= 1: instead of if abs(j - c) <= 1: on row 6? It works better. And similar on row 10.
  • Ralf
    Ralf over 5 years
    What exactly do you mean by adjacent then? I coded it as "neighbours". My code only considers the 4 surrounding cells, on positions m[r-1][c], m[r+1][c], m[r][c-1] and m[r][c+1].
  • Orbit09
    Orbit09 over 5 years
    Hi, it can be also neighbour of a neighbour with the same number. The example I gave should follow this process: the value on the fifth position is 1, then look to their neighbours: fourth position contains 1 and also sixth cell is 1. Therefore, the count is 3. Then look to the neighbours of the fourth and sixth cell: third cell contains 1, so count += 1, but in the seventh cell is 0, so on the right side the cycle stops.
  • Ralf
    Ralf over 5 years
    @Orbit09 Should the same logic you described also be aplied along the columns or just the rows?
  • Orbit09
    Orbit09 over 5 years