2011-02-02 35 views
18

मैं पाइथन में जाली मॉडल (जाली बोल्टज़मान) के लिए सिमुलेशन को लागू करने की कोशिश कर रहा हूं। जाली की प्रत्येक साइट में कई गुण होते हैं, और कुछ नियमों के अनुसार पड़ोसी साइटों के साथ बातचीत करते हैं। मुझे लगा कि यह सभी गुणों के साथ कक्षा बनाने और उस वर्ग के उदाहरणों का ग्रिड बनाने के लिए चालाक हो सकता है। (जैसा कि मैंने अजगर के साथ अनुभवहीन हूँ, यह नहीं एक अच्छा विचार बिल्कुल हो सकता है, तो मेरे दृष्टिकोण पर टिप्पणी करने के लिए स्वतंत्र महसूस।)वस्तुओं की numpy सरणी

यहाँ मैं क्या कर रहा

class site: 
    def __init__(self,a,...): 
     self.a = a 
     .... other properties ... 
    def set_a(self, new_a): 
     self.a = new_a 
की एक खिलौना उदाहरण है

अब मैं ऐसी साइटों के 2 डी/3 डी जाली (ग्रिड) से निपटना चाहता हूं इसलिए मैंने निम्नलिखित करने की कोशिश की (यहां एक उदाहरण के रूप में 2 डी 3x3 ग्रिड है, लेकिन सिमुलेशन में मुझे> 1000x1000X1000 के क्रम की आवश्यकता होगी)

lattice = np.empty((3,3), dtype=object) 
lattice[:,:] = site(3) 

अब समस्या यह है कि प्रत्येक जाली बिंदु एक ही उदाहरण को संदर्भित करता है, उदाहरण के लिए

lattice[0,0].set_a(5) 

जाली [0,2] .a से 5 के मूल्य को भी सेट करेगा। यह व्यवहार अवांछित है। समस्या प्रत्येक ग्रिड बिंदु पर मैं पाश कर सकते हैं से बचने और, तत्व द्वारा वस्तुओं तत्व आवंटित

for i in range(3): 
    for j in range(3): 
     lattice[i,j] = site(a) 

की तरह लेकिन वहाँ एक बेहतर तरीका (लूप को शामिल नहीं) एक बहुआयामी सरणी के लिए आवंटित करने के लिए वस्तुओं है करने के लिए?

धन्यवाद

+7

यदि आप> 1000x1000X1000 सरणी से निपट रहे हैं, _don't_ ऑब्जेक्ट सरणी का उपयोग करें !! यह "सामान्य" numpy सरणी का उपयोग करने की तुलना में स्मृति की भारी मात्रा का उपयोग करेगा। ऑब्जेक्ट एरे वे नहीं हैं जो आप यहां चाहते हैं ... –

+4

सिमुलेशन द्वारा मुझे लगता है कि आप द्रव सिमुलेशन का मतलब है? यदि ऐसा है, तो मैं आपको अपने दृष्टिकोण पर पुनर्विचार करने की सलाह दूंगा। शायद आपके सरणी के तत्व संख्यात्मक होना चाहिए, इसलिए आप रैखिक बीजगणित की सभी शक्तियों का उपयोग कर सकते हैं ;-)। कण प्रचार और टकराव की प्रक्रिया वैश्विक स्तर पर की जानी चाहिए! कोई भी स्थानीय ऑब्जेक्ट जाली किसी उचित गणना समय में इसे संभालने में सक्षम नहीं है। बस क्रूर, वास्तव में नहीं जानते कि आप क्या लक्ष्य कर रहे हैं ;-)। धन्यवाद – eat

+0

@eat: मैं तरल सिमुलेशन कर रहा हूँ। मैं साइट्स के जेनेरिक ग्रिड को कोड करना चाहता था, जहां सभी स्थानीय गुणों को कक्षा में एकत्र किया गया था (टक्कर मेरी पुस्तक में स्थानीय है, प्रचार नहीं है), लेकिन मुझे लगता है कि आप ठीक बाद में हैं। कम से कम bpowah मुझे सिखाया कि कैसे __init__ समारोह vectorize :) – jonalm

उत्तर

18

आप वर्ग के __init__ समारोह vectorize कर सकते हैं:

import numpy as np 

class Site: 
    def __init__(self, a): 
     self.a = a 
    def set_a(self, new_a): 
     self.a = new_a 

vSite = np.vectorize(Site) 

init_arry = np.arange(9).reshape((3,3)) 

lattice = np.empty((3,3), dtype=object) 
lattice[:,:] = vSite(init_arry) 

यह क्लीनर लग सकता है, लेकिन अपने पाशन समाधान पर कोई प्रदर्शन लाभ दिया है। सूची समझ उत्तर एक मध्यवर्ती पायथन सूची बनाता है जो प्रदर्शन को हिट करेगा।

+0

बहुत बढ़िया टिप। धन्यवाद। – jonalm

+0

+1। वेक्टरize के लिए अच्छा उदाहरण। – tom10

+0

क्या होगा यदि साइट 'एक से अधिक पैरामीटर लेती है? –

6

आप के लिए गायब टुकड़ा है कि अजगर एक संदर्भ के रूप में सब कुछ व्यवहार करता है। (कुछ "अपरिवर्तनीय" वस्तुओं, तार और संख्या और tuples, कि अधिक मान की तरह व्यवहार कर रहे हैं।) जब आप

lattice[:,:] = site(3) 

आप कह रहे हैं "अजगर कार्य करें: एक नई वस्तु site बनाने के लिए, और के प्रत्येक तत्व बता lattice उस ऑब्जेक्ट को इंगित करने के लिए। " कि यह वास्तव में मामला है देखने के लिए, कि वस्तुओं की स्मृति पतों सभी एक ही कर रहे हैं देखने के लिए सरणी प्रिंट:

array([[<__main__.Site object at 0x1029d5610>, 
     <__main__.Site object at 0x1029d5610>, 
     <__main__.Site object at 0x1029d5610>], 
     [<__main__.Site object at 0x1029d5610>, 
     <__main__.Site object at 0x1029d5610>, 
     <__main__.Site object at 0x1029d5610>], 
     [<__main__.Site object at 0x1029d5610>, 
     <__main__.Site object at 0x1029d5610>, 
     <__main__.Site object at 0x1029d5610>]], dtype=object) 

पाश तरह से यह करने के लिए एक सही तरीका है। Numpy arrays के साथ, यह आपका सबसे अच्छा विकल्प हो सकता है; अजगर सूचियों के साथ, आप भी एक सूची समझ इस्तेमाल कर सकते हैं:

lattice = np.array([ [Site(i + j) for i in range(3)] for j in range(3) ], 
        dtype=object) 

अब जब आप lattice प्रिंट, यह

array([[<__main__.Site object at 0x1029d53d0>, 
     <__main__.Site object at 0x1029d50d0>, 
     <__main__.Site object at 0x1029d5390>], 
     [<__main__.Site object at 0x1029d5750>, 
     <__main__.Site object at 0x1029d57d0>, 
     <__main__.Site object at 0x1029d5990>], 
     [<__main__.Site object at 0x1029d59d0>, 
     <__main__.Site object at 0x1029d5a10>, 
     <__main__.Site object at 0x1029d5a50>]], dtype=object) 
है:

lattice = [ [Site(i + j) for i in range(3)] for j in range(3) ] 

आप numpy.array निर्माण के साथ एक सूची समझ का उपयोग कर सकते

ताकि आप देख सकें कि वहां मौजूद हर वस्तु अद्वितीय है।

आपको यह भी ध्यान रखना चाहिए कि "सेटर" और "गेटर" विधियां (उदा।, set_a) गैर-पायथनिक हैं। सेट करना और सीधे गुण प्राप्त करना बेहतर है, और फिर @property सजावट का उपयोग करें यदि आपको वास्तव में किसी विशेषता को लेखन पहुंच को रोकने की आवश्यकता है।

यह भी ध्यान दें कि पाइथन कक्षाओं को कैमेलकेस का उपयोग करके लिखे जाने के लिए मानक है, न कि लोअरकेस।

+0

इनपुट के लिए बहुत बहुत धन्यवाद। लेकिन मुझे नहीं पता कि मैं आपको सही तरीके से समझता हूं; एक वर्ग उदाहरण ए = साइट (4,5) के लिए, क्या यह 'एसेट_ए (6)' से 'एए = 6' के साथ एक चर अद्यतन करने के लिए बेहतर (अधिक पायथनिक) है? पाइथोनिक कोडिंग के लिए अच्छे गाइड पर कोई संदर्भ? – jonalm

+0

इसके साथ सावधान रहें 'साइट' लागू '__len__' है। –

3

मैं के बारे में बेहतर पता नहीं है, लेकिन छोरों की एक स्पष्ट सेट के लिए एक विकल्प के रूप में, आप

lattice = np.empty((3,3), dtype=object) 
lattice.flat = [site(3) for _ in lattice.flat] 

जो जाली के जो भी आकार काम करना चाहिए लिख सकते हैं।

संबंधित मुद्दे