2015-01-10 10 views
5

से पहले मैट्रिक्स के विकर्ण तत्वों को प्रभावित करें मैं 2 डी मैट्रिक्स से विकर्ण तत्वों को बदलना चाहता हूं। ये मुख्य और गैर-मुख्य विकर्ण दोनों हैं।बेवकूफ: 1.10

numpy.diagonal() NumPy 1.10 में, यह एक पढ़ें/लिखें दृश्य लौटने के लिए, लौटे सरणी के लिए लेखन अपने मूल सरणी बदल जाएगा।

numpy.fill_diagonal(), numpy.diag_indices() केवल मुख्य-विकर्ण तत्वों के साथ काम करता है

यहाँ मेरी उपयोग मामला है: मैं निम्नलिखित रूप है, जिनमें से एक मैट्रिक्स से बनाना चाहते हैं बहुत तुच्छ का उपयोग कर विकर्ण अंकन दिया मेरे पास है कि सभी एक्स, y, सरणियों के रूप में z

matrix

+0

क्या 'numpy.diag' के बारे में? – talonmies

+1

मुझे लगता है कि 'np.diag' कॉल 'np.diagonal' जो, Numpy 1.10 से पहले, प्रस्तुत करता है [कठिनाइयों] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.diagonal.html) सरणी में मूल्य लिखने की कोशिश करते समय। –

+0

शायद ['scipy.sparse.diags'] पर एक नज़र डालें (http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.diags.html) और [' scipy .sparse।dia_matrix'] (http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.dia_matrix.htm)। –

उत्तर

4

आप हमेशा मूल्य ओ असाइन करने के लिए स्लाइसिंग का उपयोग कर सकते हैं विकर्णों के लिए आर सरणी।

पंक्ति सूचकांक की सूची में और कॉलम इंडेक्स की एक सूची में उत्तीर्ण करने से आप सीधे स्थानों (और कुशलता से) तक पहुंच सकते हैं। उदाहरण के लिए:

>>> z = np.zeros((5,5)) 
>>> z[np.arange(5), np.arange(5)] = 1 # diagonal is 1 
>>> z[np.arange(4), np.arange(4) + 1] = 2 # first upper diagonal is 2 
>>> z[np.arange(4) + 1, np.arange(4)] = [11, 12, 13, 14] # first lower diagonal values 

को शून्य z की सरणी परिवर्तन: एक k x k सरणी z कहा जाता है के लिए

array([[ 1., 2., 0., 0., 0.], 
     [ 11., 1., 2., 0., 0.], 
     [ 0., 12., 1., 2., 0.], 
     [ 0., 0., 13., 1., 2.], 
     [ 0., 0., 0., 14., 1.]]) 

सामान्य तौर पर, आप के साथ i वें ऊपरी विकर्ण सेट कर सकते हैं

z[np.arange(k-i), np.arange(k-i) + i] 

और i वें निम्न विकर्ण

के साथ
z[np.arange(k-i) + i, np.arange(k-i)] 

नोट: यदि आप np.arange कई बार फोन करने से बचना चाहते हैं, तो आप बस ix = np.arange(k) एक बार लिख सकते हैं और फिर आवश्यकतानुसार कि सीमा काट:

np.arange(k-i) == ix[:-i] 
4

इस प्रयास करें:

>>> A = np.zeros((6,6)) 
>>> i,j = np.indices(A.shape) 
>>> z = [1, 2, 3, 4, 5] 

अब आप सहज किसी भी विकर्ण पहुंच सकता है: एक ही तरह से आप A[i==j] को सरणियों असाइन कर सकते हैं में

>>> A[i==j-1] = z 
>>> A 
array([[ 0., 1., 0., 0., 0., 0.], 
     [ 0., 0., 2., 0., 0., 0.], 
     [ 0., 0., 0., 3., 0., 0.], 
     [ 0., 0., 0., 0., 4., 0.], 
     [ 0., 0., 0., 0., 0., 5.], 
     [ 0., 0., 0., 0., 0., 0.]]) 

, आदि

+0

@ajcrs उत्तर के साथ प्रदर्शन की तुलना नहीं की है, लेकिन मुझे सादगी के लिए यह पसंद है। – FooBar

+0

@FooBar यह विधि निश्चित रूप से मेरे से वाक्य रचनात्मक रूप से सरल है :-) लेकिन बड़े पैमाने पर matrices के लिए एक मुखौटा ('i == j-1' के साथ) का प्रदर्शन, कुशल नहीं है। 1000x1000 मैट्रिक्स पर, पहले ऊपरी विकर्ण को सीधे इंडेक्स निर्दिष्ट करने से लगभग 100 गुना धीमा है। ऐसा इसलिए है क्योंकि आपको बूलियन मास्क बनाने के लिए दस लाख '==' तुलना करने की आवश्यकता है (स्मृति में बड़े बूलियन मैट्रिक्स का उल्लेख करने के लिए नहीं)। चाहे यह मामला आपके उपयोग के मामले पर निर्भर करता है या नहीं। –

1

यहाँ सिर्फ मनोरंजन के लिए एक और तरीका है। आप जिस विकर्ण की जरूरत है उसे देखने के लिए आप अपना खुद का विकर्ण कार्य लिख सकते हैं।

import numpy as np 

def diag(a, k=0): 
    if k > 0: 
     a = a[:, k:] 
    elif k < 0: 
     a = a[-k:, :] 

    shape = (min(a.shape),) 
    strides = (sum(a.strides),) 
    return np.lib.stride_tricks.as_strided(a, shape, strides) 

a = np.arange(20).reshape((4, 5)) 
diag(a, 2)[:] = 88 
diag(a, -2)[:] = 99 
print(a) 
# [[ 0 1 88 3 4] 
# [ 5 6 7 88 9] 
# [99 11 12 13 88] 
# [15 99 17 18 19]] 
संबंधित मुद्दे