2016-03-10 7 views
5

मान लीजिए a के सभी चक्रीय बदलावों के 2 डी सरणी n तत्वों के साथ कुछ 1d numppy.array है:एक -1 डी सरणी

a = np.array([a_0, a_1, ..., a_n_minus_1]) 

मैं 2 डी जेनरेट करना चाहते हैं (एन एक्स एन) numpy.array युक्त,

np.array([[a_0, a_1, ..., a_n_minus_1], [a_n_minus_1, a_0, a_1, ...], ...]]) 
: पंक्ति मैं, मैं a की वें चक्रीय बदलाव पर

अधिमानतः बिना लूप के। यह कुशलतापूर्वक कैसे किया जा सकता है?

(समारोह np.roll संबंधित लगता है, लेकिन जाहिरा तौर पर ले जाता है केवल एक अदिश shift।)

+0

कुशलता से ऐसा करने के लिए चाल विकर्ण उपयोग करने के लिए है। उदाहरण के लिए, मुख्य विकर्ण सभी पहला तत्व होगा, आदि –

+0

@ जोकिंगटन वे शांत, धन्यवाद! IIUC, आप इस तथ्य का उपयोग करना चाहते हैं कि एक चक्रीय बदलाव को रैखिक परिवर्तन के रूप में माना जा सकता है, हाँ? –

+0

@ जोकिंगटन वास्तव में, यह बहुत अच्छा लगता है, लेकिन मैं इसे समझ नहीं सकता - अलग रैखिक परिवर्तन करने वाले मैट्रिस उत्पन्न करना बहुत महंगा होगा, नहीं? –

उत्तर

9

आप वास्तव में एक मैट्रिक्स Circulant निर्माण कर रहे हैं। बस scipy circulant function का उपयोग करें। सावधान रहो, क्योंकि आप पहले ऊर्ध्वाधर स्तंभ की पहली पंक्ति को पारित करना होगा, नहीं:

from scipy.linalg import circulant 
circulant([1,4,3,2] 
> array([[1, 2, 3, 4], 
     [4, 1, 2, 3], 
     [3, 4, 1, 2], 
     [2, 3, 4, 1]] 

संदर्भ के लिए, Circulant मैट्रिक्स बहुत बहुत अच्छा properties है।

2

आप हाथ से यह करने के लिए चाहते हैं, बस np.tile का उपयोग करें:

import numpy as np 
a = np.array([1,2,3]) 

टाइल के साथ यह प्रतिकृति लेकिन एक बार और वास्तव में चाहता था "बदलाव"

b = np.tile(a, a.size+1) 
# [1 2 3 1 2 3 1 2 3 1 2 3] 

पाने के लिए जरूरत से फिर नयी आकृति प्रदान यह तो यह आकार के साथ एक 2 डी मैट्रिक्स है (a, a+1)

b.reshape(a.size, a.size+1) 
#[[1 2 3 1] 
# [2 3 1 2] 
# [3 1 2 3]] 

ठीक है, टी क्या हो रहा है यह देखने के लिए टोपी सिर्फ एक डिबगिंग कदम था। लेकिन अगर आप इसे देखते हैं, तो आपको पता है कि आपको अंतिम कॉलम को हटाना होगा:

b.reshape(a.size, a.size+1)[:,:-1] 

और फिर आपके पास वांछित परिणाम है।


यह भी (लगभग) आर्बिटरी बदलाव की अनुमति के लिए सामान्यीकृत किया जा सकता:

shift = 3 
a = np.array([...]) 
b = np.tile(a, a.size+shift) 
res = b.reshape(a.size, a.size+shift)[:,:-shift] 
संबंधित मुद्दे