Как перебрать столбец матрицы в python - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть матрица со значениями только ячеек 0 или 1.

Я хочу посчитать, сколько единиц или нулей имеется в одной строке или столбце данной ячейки.

Например, значение matrix[r][c] равно 1, поэтому я хочу знать, сколько их в одной строке. Этот код делает это:

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

Цикл for выполняет итерацию по одной и той же строке и подсчитывает все единицы (ячейки с одинаковым значением).

Что если я хочу сделать тот же процесс со столбцами? Буду ли я перебирать всю матрицу или это возможно только через один столбец?

PS: я не хочу использовать numpy, transpose или zip; лучше с составным циклом.

Ответы [ 4 ]

0 голосов
/ 01 ноября 2018

Это решение с одним циклом for:

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

for index, row in enumerate(matrix):
  if index == r:
    count_in_row = row.count(value)
  if row[c] == value:
    count_in_column += 1

print(count_in_row, count_in_column)
0 голосов
/ 01 ноября 2018

Я не буду решать это за вас, но, возможно, намекну в правильном направлении ...

# 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]
0 голосов
/ 01 ноября 2018

Вы можете создать список для строк и столбцов и просто перебрать свою матрицу один раз , добавляя при этом правильные части:

Создать демодату:

import random

random.seed(42)

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

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

Выход:

[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]

Считайте вещи:

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)

Выход:

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

Меньше кода, но требуется 2 полных прохода по матрице с помощью zip () для транспонирования данных:

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

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

Вывод: (тоже самое)

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

Возможно, вам придется рассчитать время, но издержки двух полных итераций и архивирования могут все же стоить того, так как способ zip () наследуемо более оптимизирован, чем цикл по списку. Компромисс может стоить только / вверх / вверх от определенных размеров матрицы ...

0 голосов
/ 01 ноября 2018

Вы не указали тип данных вашей матрицы. Если это список списков, то нет способа «получить только один столбец», но код все еще похож (если предположить, что r и c имеют тип int):

Я добавил функциональность для подсчета только ячеек, смежных с рассматриваемой ячейкой (сверху, снизу, слева и справа; НЕ учитывает диагонали); это делается для проверки того, что разница между индексами не превышает 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

Или если следовать тому, как вы его начали (целые строки и столбцы, а не только соседние):

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

Если вы будете делать это для большого количества ячеек, то есть более эффективные способы сделать это (даже без numpy, но numpy, безусловно, очень хороший вариант).

...