2013-08-02 3 views

答えて

18

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.]]) 
+3

これは素晴らしいソリューションです。提案されたすべてのソリューションの中で、シンプルさとパフォーマンスのバランスがよくなっています。 numpyのdiag関数を使用して、どのスーパー/サブ対角線を更新してから対角のビューを返すかを指定できます。これは最も直感的で最速のものになります。 –

4
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.]]) 

あなただけではなくarrnp.ascontiguousarray(arr)を返すことでこの問題を回避できたが、その後using_tile_and_strideがより遅くなるだろうusing_put。したがって、配列を変更する場合は、using_putを選択することをお勧めします。

0

この質問に対する答えを使用して: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 
5

これは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]] 
関連する問題