2015-11-04 2 views
2

Так что моя цель заключается в следующем, учитывая размер матрицы s, я пытаюсь создать матрицу, которая выглядит следующим образом, но размер sxs:Построение специальной матрицы в NumPy динамически

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

Для размера 4x4, это будет выглядеть примерно так:

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

Поэтому вы можете наблюдать картину: есть s-1 количество перекрывающихся MINI 2x2 ОДНИ матриц.

Я думал о создании матрицы 2x2 одни, а затем с помощью динамического реферирования (для цикла?) Как B[:-1,:-1] = ones_matrix, где B является Нули матрицей размера sxs. Но я не уверен, как включить цикл for здесь, потому что если мы возьмем матрицу 4x4, тогда нам нужно будет ссылаться на B тремя способами: B[:-1,:-1] = ones_matrix, B[1:-1,1:-1] = ones_matrix, B[2:,2:]=ones_matrix. И я не могу найти способ сделать это динамически для нулевой матрицы n. Есть ли другой способ сделать это?

+0

Я думаю, что знаю, как это сделать. Я могу фактически использовать динамическую ссылку –

+1

Это просто [тридиагональная матрица] (https://en.wikipedia.org/wiki/Tridiagonal_matrix), может упростить объяснения в будущем. – Daniel

ответ

3

Метод # 1: Вместо связки 2x2, было бы проще смотреть на него как на три диагоналя 1 и объединить их:

>>> s = 3 
>>> np.diag([1]*s,0) + np.diag([1]*(s-1),-1) + np.diag([1]*(s-1), 1) 
array([[1, 1, 0], 
     [1, 1, 1], 
     [0, 1, 1]]) 
>>> s = 4 
>>> np.diag([1]*s,0) + np.diag([1]*(s-1),-1) + np.diag([1]*(s-1), 1) 
array([[1, 1, 0, 0], 
     [1, 1, 1, 0], 
     [0, 1, 1, 1], 
     [0, 0, 1, 1]]) 

Способ № 2: (вдохновленный ответ Divankar в), мы можем думать с точки зрения расстояния от центра:

>>> s = 4 
>>> i,j = np.indices((s,s)) 
>>> (abs(i-j) <= 1).astype(int) 
array([[1, 1, 0, 0], 
     [1, 1, 1, 0], 
     [0, 1, 1, 1], 
     [0, 0, 1, 1]]) 

Способ № 3: мы могли бы воспользоваться tril или triu и сделать некоторые арифметические:

>>> m = np.tril(np.ones((s,s)),1) 
>>> m * m.T 
array([[ 1., 1., 0., 0., 0.], 
     [ 1., 1., 1., 0., 0.], 
     [ 0., 1., 1., 1., 0.], 
     [ 0., 0., 1., 1., 1.], 
     [ 0., 0., 0., 1., 1.]]) 
>>> m = np.tril(np.ones((s,s)),2) 
>>> m * m.T 
array([[ 1., 1., 1., 0., 0.], 
     [ 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1.], 
     [ 0., 1., 1., 1., 1.], 
     [ 0., 0., 1., 1., 1.]]) 
+0

О, это здорово! Спасибо –

+0

Что делать, если вы хотите не целое значение в диагоналях, а говорите всю матрицу! Итак, у вас есть диагональные матрицы. Не могли бы вы пойти np.diag (A * s, 0)? –

+0

@ isquared-KeepitReal: это немного другой вопрос. Однако вы можете открыть новый с некоторыми примерами того, что вы хотите! – DSM

1

Векторизованное подход с broadcasting -

A = np.arange(s) 
out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int) 

Sample перспективе -

In [60]: s = 3 
    ...: A = np.arange(s) 
    ...: out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int) 
    ...: 

In [61]: out 
Out[61]: 
array([[1, 1, 0], 
     [1, 1, 1], 
     [0, 1, 1]]) 

In [62]: s = 4 
    ...: A = np.arange(s) 
    ...: out = ((A[:,None] < A+2) & (A[:,None] > A-2)).astype(int) 
    ...: 

In [63]: out 
Out[63]: 
array([[1, 1, 0, 0], 
     [1, 1, 1, 0], 
     [0, 1, 1, 1], 
     [0, 0, 1, 1]]) 
+0

@DSM Отредактировано чем-то, что работает! :) – Divakar

+0

Намного лучше. :-) – DSM

0

Вы можете использовать sympy.Matrix также:

from sympy import Matrix 
Matrix(4, 4, lambda i,j: 1 if (-2<i-j<2) else 0) 

Matrix([ 
[1, 1, 0, 0], 
[1, 1, 1, 0], 
[0, 1, 1, 1], 
[0, 0, 1, 1]]) 
+0

Спасибо, я проверю это –