2013-08-02 8 views
11

में विशेष विकर्ण मैट्रिक्स करें:मैं एक numpy सरणी कि इस तरह दिखता है बनाने के लिए कोशिश कर रहा हूँ Numpy

[a b c  ] 
[ a b c  ] 
[ a b c ] 
[  a b c ] 

तो यह मुख्य विकर्ण और यह ऊपर दो विकर्ण को अद्यतन करने में शामिल है।

ऐसा करने का एक प्रभावी तरीका क्या होगा?

उत्तर

18

आप अपने सरणी के सूचकांक प्राप्त करने के लिए np.indices का उपयोग कर सकते हैं और फिर उन मानों को असाइन कर सकते हैं जहां आप चाहते हैं।

a = np.zeros((5,10)) 
i,j = np.indices(a.shape) 

i,j क्रमशः लाइन और कॉलम इंडेक्स हैं।

a[i==j] = 1. 
a[i==j-1] = 2. 
a[i==j-2] = 3. 

परिणाम देगा में:

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

अन्य, धीमी विकल्प शामिल हैं:

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))) 

आप using_tile_and_stride उपयोग करते हैं, ध्यान दें कि सरणी के लिए उपयुक्त है केवल पढ़ने के उद्देश्य। अन्यथा, यदि आप सरणी संशोधित करने के लिए प्रयास करने के लिए थे, तो आप आश्चर्य जब कई सरणी स्थानों एक साथ बदल हो सकता है:

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 बेहतर विकल्प होगा।

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]] 
संबंधित मुद्दे