で特別な対角行列を作る:私はこのようになりますnumpyの配列を作るしようとしていますnumpyの
[a b c ]
[ a b c ]
[ a b c ]
[ a b c ]
だから、これは主対角とその上の対角線の更新が含ま。
これを行う効率的な方法は何でしょうか?
で特別な対角行列を作る:私はこのようになりますnumpyの配列を作るしようとしていますnumpyの
[a b c ]
[ a b c ]
[ a b c ]
[ a b c ]
だから、これは主対角とその上の対角線の更新が含ま。
これを行う効率的な方法は何でしょうか?
np.indices
を使用すると、配列のインデックスを取得し、必要な値を割り当てることができます。
a = np.zeros((5,10))
i,j = np.indices(a.shape)
i,j
はそれぞれ行と列のインデックスです。
array([[ 1., 2., 3., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 1., 2., 3., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 1., 2., 3., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 1., 2., 3., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 2., 3., 0., 0., 0.]])
import numpy as np
def using_tile_and_stride():
arr = np.tile(np.array([10,20,30,0,0,0], dtype='float'), (4,1))
row_stride, col_stride = arr.strides
arr.strides = row_stride-col_stride, col_stride
return arr
In [108]: using_tile_and_stride()
Out[108]:
array([[ 10., 20., 30., 0., 0., 0.],
[ 0., 10., 20., 30., 0., 0.],
[ 0., 0., 10., 20., 30., 0.],
[ 0., 0., 0., 10., 20., 30.]])
その他、低速の選択肢は、次のとおりです:
a[i==j] = 1.
a[i==j-1] = 2.
a[i==j-2] = 3.
はになりますあなたがusing_tile_and_stride
を使用している場合
import numpy as np
import numpy.lib.stride_tricks as stride
def using_put():
arr = np.zeros((4,6), dtype='float')
a, b, c = 10, 20, 30
nrows, ncols = arr.shape
ind = (np.arange(3) + np.arange(0,(ncols+1)*nrows,ncols+1)[:,np.newaxis]).ravel()
arr.put(ind, [a, b, c])
return arr
def using_strides():
return np.flipud(stride.as_strided(
np.array([0, 0, 0, 10, 20, 30, 0, 0, 0], dtype='float'),
shape=(4, 6), strides = (8, 8)))
は、アレイがためにのみ適切であることに注意してください読み取り専用の目的。あなたは、配列を変更しようとした場合、複数のアレイ位置が同時に変化したときにそれ以外の場合、あなたは驚くかもしれません:
In [32]: arr = using_tile_and_stride()
In [33]: arr[0, -1] = 100
In [34]: arr
Out[34]:
array([[ 10., 20., 30., 0., 100.],
[ 100., 10., 20., 30., 0.],
[ 0., 0., 10., 20., 30.],
[ 30., 0., 0., 10., 20.]])
あなただけではなくarr
のnp.ascontiguousarray(arr)
を返すことでこの問題を回避できたが、その後using_tile_and_stride
がより遅くなるだろうusing_put
。したがって、配列を変更する場合は、using_put
を選択することをお勧めします。
この質問に対する答えを使用して:changing the values of the diagonal of a matrix in numpy、それぞれの対角線のビューを取得するためにいくつかトリッキーなスライスを行い、割り当てを行います。 この場合、それだけで次のようになります。
import numpy as np
A = np.zeros((4,6))
# main diagonal
A.flat[:A.shape[1]**2:A.shape[1]+1] = a
# first superdiagonal
A.flat[1:max(0,A.shape[1]-1)*A.shape[1]:A.shape[1]+1] = b
# second superdiagonal
A.flat[2:max(0,A.shape[1]-2)*A.shape[1]:A.shape[1]+1] = c
これはToeplitz matrixの一例である - あなたはscipy.linalg.toeplitz
を使用して構築することができます。
import numpy as np
from scipy.linalg import toeplitz
first_row = np.array([1, 2, 3, 0, 0, 0])
first_col = np.array([1, 0, 0, 0])
print(toeplitz(first_col, first_row))
# [[1 2 3 0 0 0]
# [0 1 2 3 0 0]
# [0 0 1 2 3 0]
# [0 0 0 1 2 3]]
これは素晴らしいソリューションです。提案されたすべてのソリューションの中で、シンプルさとパフォーマンスのバランスがよくなっています。 numpyのdiag関数を使用して、どのスーパー/サブ対角線を更新してから対角のビューを返すかを指定できます。これは最も直感的で最速のものになります。 –