Генерация полосатых матриц с использованием NumPy - PullRequest
0 голосов
/ 23 сентября 2018

Я использую следующий фрагмент кода для создания полосовой матрицы из генератора g:

def banded(g, N):
    """Creates a `g` generated banded matrix with 'N' rows"""
    n=len(g)
    T = np.zeros((N,N+n-1))
    for x in range(N):
        T[x][x:x+n]=g
    return T

Использование просто как:

banded([1,2,3], 3)

и этовозвращает

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

Он будет использоваться в основном для решения модели конечных разностей с данным трафаретом, например (-1, 1)

Есть ли лучший способ для генерации этого трафарета?Я не смог найти ни одной хорошей функции NumPy для этого.

Лучше я имею в виду, быстрее, используя меньше памяти, удаляя цикл из python и отправляя в стек Numpy.Все (или все) из них являются улучшениями.

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Вот один с np.lib.stride_tricks.as_strided, чтобы дать нам 2D представление для дополненной нулями версии ввода 1D и, как таковую, довольно эффективной памяти и, следовательно, производительной.Этот трюк был исследован много раз - 1, 2.

Таким образом, реализация будет -

def sliding_windows(a, W):
    a = np.asarray(a)
    p = np.zeros(W-1,dtype=a.dtype)
    b = np.concatenate((p,a,p))
    s = b.strides[0]
    strided = np.lib.stride_tricks.as_strided
    return strided(b[W-1:], shape=(W,len(a)+W-1), strides=(-s,s))

Примеры прогонов -

In [99]: a = [1,2,3]

In [100]: sliding_windows(a, W=3)
Out[100]: 
array([[1, 2, 3, 0, 0],
       [0, 1, 2, 3, 0],
       [0, 0, 1, 2, 3]])

In [101]: a = [1,2,3,4,5]

In [102]: sliding_windows(a, W=3)
Out[102]: 
array([[1, 2, 3, 4, 5, 0, 0],
       [0, 1, 2, 3, 4, 5, 0],
       [0, 0, 1, 2, 3, 4, 5]])

С той же философией, но менее сложной версией, мы можем также использовать np.lib.stride_tricks.as_strided на основе scikit-image's view_as_windows, чтобы получить скользящие окна. Подробнее об использовании as_strided на основе view_as_windows.

from skimage.util.shape import view_as_windows

def sliding_windows_vw(a, W):
    a = np.asarray(a)
    p = np.zeros(W-1,dtype=a.dtype)
    b = np.concatenate((p,a,p))
    return view_as_windows(b,len(a)+W-1)[::-1]
0 голосов
/ 23 сентября 2018

Вы можете использовать scipy.sparse.diags:

Вход:

diags([1, 2, 3], [0, 1, 2], shape=(3,5)).toarray()

Выход:

array([[ 1.,  2.,  3.,  0.,  0.],
      [ 0.,  1.,  2.,  3.,  0.],
      [ 0.,  0.,  1.,  2.,  3.]])

Второй список, [0, 1, 2],список смещенийОн говорит, как смещение от диагонали вы хотите, чтобы определенный элемент был.

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