Преобразование матрицы в Python
Имеется матрица вида:
[0, 0, 0, 0, 0, 0, 0
0, 0, 1, 1, 1, 0, 0
0, 1, 1, 1, 1, 1, 0
0, 1, 1, 1, 1, 1, 0
0, 0, 1, 1, 1, 0, 0
0, 0, 0, 0, 0, 0, 0]
Необходимо создать массив данных несущих в себе информацию о значениях отличных от 0 и их координатах в исходном массиве. Примерно [ x, y, 1] и т.д.
import pandas as pd
def row(s):
return s[0] != '0'
file = 'samp.xlsx'
xl = pd.ExcelFile(file)
print(xl.sheet_names)
df1 = xl.parse('Лист1')
print (df1)
df2 = filter(row, df1)
print (df2)
В меру понимания пробовал фильтрацию, но не выводится матрица df2
Ответы (3 шт):
Самый просто способ:
matrix = [[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]
arr = []
for x in range(len(matrix)):
for y in range(len(matrix[x])):
if matrix[x][y] != 0:
arr.append([x, y, matrix[x][y]])
for i in arr:
print(' '.join(list(map(str, i))))
Если обязателен numpy, то я тут не помощник...
Ну, вероятно, можно так:
import numpy as np
a = [[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]
arr = np.array(a)
coords = np.argwhere(arr!=0)
res = list(zip(coords[:,0], coords[:,1], arr[coords[:,0], coords[:,1]]))
res:
[(1, 2, 1), (1, 3, 1), (1, 4, 1), (2, 1, 1), (2, 2, 1), (2, 3, 1), (2, 4, 1), (2, 5, 1), (3, 1, 1), (3, 2, 1), (3, 3, 1), (3, 4, 1), (3, 5, 1), (4, 2, 1), (4, 3, 1), (4, 4, 1)]
Без numpy
Перебираем строки, в строках перебираем элементы. Если элемент не нулевой выдаём адрес и значение. На верхнем уровне собираем всё в список:
def nonzeros(a):
for i, r in enumerate(a):
for j, v in enumerate(r):
if v != 0:
yield i, j, v
a = [
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0]
]
b = list(nonzeros(a))
print(b)
$ python convert.py [(1, 2, 1), (1, 3, 1), (1, 4, 1), (2, 1, 1), (2, 2, 1), (2, 3, 1), (2, 4, 1), (2, 5, 1), (3, 1, 1), (3, 2, 1), (3, 3, 1), (3, 4, 1), (3, 5, 1), (4, 2, 1), (4, 3, 1), (4, 4, 1)]
С numpy
b = np.nonzero(a) возвращает списки ненулевых координат: отдельно список индексов строк, отдельно список индексов столбцов.
c = a[b] возвращает все значения адресованные b.
b + (c, ) собирает индексы и значения вместе.
np.column_stack превращает список массивов в единый двумерный массив. Это аналог zip.
import numpy as np
a = np.array([
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0]
])
# b = (
# array([1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4]),
# array([2, 3, 4, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 2, 3, 4])
# )
b = np.nonzero(a)
# c = [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
c = a[b]
# d = [[1 2 1] [1 3 1] ... [4 4 1]]
# or use d = list(zip(*b, c))
d = np.column_stack(b + (c, ))
print(d)
$ python convert.py [[1 2 1] [1 3 1] [1 4 1] [2 1 1] [2 2 1] [2 3 1] [2 4 1] [2 5 1] [3 1 1] [3 2 1] [3 3 1] [3 4 1] [3 5 1] [4 2 1] [4 3 1] [4 4 1]]