Преобразование матрицы положительных целых чисел в булеву матрицу без циклов - PullRequest
2 голосов
/ 13 января 2020

Я пытаюсь написать код в Python, используя NumPy. Я не уверен, что это возможно, но вот что я пытаюсь сделать:

У меня есть 2D матрица a формы (rows, cols) с положительными целыми числами, и я хочу определить матрицу b такой, что если a [i, j] = x, то b [i, j + 1] = b [i, j + 2] = ... = b [i, j + x] = 1 (b инициализируется как a матрица нулей).

Можно предположить, что для каждого j, x: j + x <= cols-1. </p>

Например, если a равно:

[0 2 0 0]
[0 2 0 0]
[3 0 0 0]
[2 0 1 0]

Тогда b должно быть:

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

Можно ли сделать вышеупомянутое в Python с NumPy без использования циклов ?

Если это невозможно сделать без петель, есть ли эффективный способ сделать это? (rows и cols могут быть большими числами.)

Ответы [ 2 ]

1 голос
/ 13 января 2020

Если это невозможно сделать без циклов, есть ли эффективный способ сделать это? (rows и cols могут быть большими числами.)

Извините, я не знаю функцию NumPy, которая могла бы помочь в вашей ситуации, но я думаю, что обычная l oop и индексирование массива должно быть достаточно быстрым:

import numpy as np

a = np.array([
    [0, 2, 0, 0],
    [0, 2, 0, 0],
    [3, 0, 0, 0],
    [2, 0, 1, 0],
])

b = np.zeros(a.shape)
for i, x in enumerate(a.flat):
    b.flat[i + 1 : i + 1 + x] = 1

print(b)

Что выводит ожидаемый результат:

[[0. 0. 1. 1.]
 [0. 0. 1. 1.]
 [0. 1. 1. 1.]
 [0. 1. 1. 1.]]
0 голосов
/ 14 января 2020

Вот немного оптимизированное решение @ finefoot

aa = a.ravel()
b = np.zeros_like(aa)
for i, x in enumerate(aa):
    if x != 0:
        b[i + 1 : i + 1 + x] = 1
b = b.reshape(a.shape) 

А вот еще одно решение, которое немного быстрее, но менее читаемо:

from itertools import chain

aa = a.ravel()
b = np.zeros_like(aa)
w = np.nonzero(aa)[0]
ranges = (range(s, e) for s, e in zip(w + 1, w + 1 + aa[w]))
for r in chain.from_iterable(ranges):
    b[r] = 1
b = b.reshape(a.shape)

Дает правильные результаты при условии, что j,x: j+x<=cols-1 , Оба решения используют for-l oop, но я не думаю, что это возможно сделать иначе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...