2012-02-26 10 views
9

मैं पाइथन के लिए नया हूं, और समझ में नहीं आता कि .tyty क्या करता है। उदाहरण के लिए:क्या करता है। टाइप करें?

>>> aa 
array([1, 2, 3, 4, 5, 6, 7, 8]) 
>>> aa.dtype = "float64" 
>>> aa 
array([ 4.24399158e-314, 8.48798317e-314, 1.27319747e-313, 
    1.69759663e-313]) 

मैंने सोचा, dtype आ की संपत्ति है, जो पूर्णांक होना चाहिए, और अगर मैं आवंटित aa.dtype = "float64" तो आ सरणी ([1.0, 2.0, 3.0, 4.0 होना चाहिए 5.0, 6.0, 7.0, 8.0])।

यह इसके मूल्य और आकार को क्यों बदलता है? इसका क्या मतलब है?

मैं वास्तव में कोड का एक पैसा से तैयार कर रही थी, और मैं इसे यहाँ पेस्ट जाएगा:

def to_1d(array): 
"""prepares an array into a 1d real vector""" 
    a = array.copy() # copy the array, to avoid changing global 
    orig_dtype = a.dtype 
    a.dtype = "float64" # this doubles the size of array 
    orig_shape = a.shape 
    return a.ravel(), (orig_dtype, orig_shape) #flatten and return 

मुझे लगता है कि यह नहीं होना चाहिए इनपुट सरणी का मूल्य बदल लेकिन केवल अपने आकार बदल जाते हैं। फ़ंक्शन कैसे काम करता है

+0

आप चाहते हैं 'aa.astype (float) ' –

+0

संदेह में, [मैन्युअल पढ़ें] (http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#arrays-dtypes) –

+0

मैंने मैनुअल को समझने की कोशिश की है, हालांकि, इसकी अंग्रेजी और कंप्यूटिंग भाषा मेरे लिए बहुत कठिन है, मुझे जरूरी सूचनाएं नहीं मिल सकतीं। – user1233157

उत्तर

33

सबसे पहले, आप से सीख रहे हैं कोड दोषपूर्ण है। यह निश्चित रूप से ऐसा नहीं करता है जो मूल लेखक ने सोचा था कि यह कोड में टिप्पणियों के आधार पर किया गया था।

क्या लेखक शायद मतलब यह था:

def to_1d(array): 
    """prepares an array into a 1d real vector""" 
    return array.astype(np.float64).ravel() 

हालांकि, अगर array हमेशा जटिल संख्याओं की एक सरणी होने जा रहा है, तो मूल कोड कुछ समझ में आता है।

केवल मामलों में जहां सरणी देखने वाले लोग (a.dtype = 'float64'a = a.view('float64') कर के बराबर है) दोगुना हो जाएगा इसके आकार अगर यह एक जटिल श्रृंखला (numpy.complex128) या 128-बिट चल बिन्दु सरणी है। किसी भी अन्य प्रकार के लिए, यह ज्यादा समझ में नहीं आता है।

जटिल सरणी के विशिष्ट मामले के लिए, मूल कोड np.array([0.5+1j, 9.0+1.33j])np.array([0.5, 1.0, 9.0, 1.33]) में कुछ परिवर्तित करेगा।

एक क्लीनर तरीका लिखने के लिए है कि होगा:

def complex_to_iterleaved_real(array): 
    """prepares a complex array into an "interleaved" 1d real vector""" 
    return array.copy().view('float64').ravel() 

(मैं, मूल dtype और आकार लौटने पल के लिए के बारे में हिस्सा अनदेखी कर रहा हूँ।)


numpy पर पृष्ठभूमि सरणी

यह समझाने के लिए कि यहां क्या हो रहा है, आपको कुछ समझने की आवश्यकता है कि क्या numpy arrays हैं।

एक numpy सरणी में "कच्चे" मेमोरी बफर होता है जिसे "दृश्य" के माध्यम से सरणी के रूप में व्याख्या किया जाता है। आप विचारों के रूप में सभी numpy arrays के बारे में सोच सकते हैं।

दृश्य, गंदे अर्थ में, प्रतिलिपि बनाने के बिना एक ही मेमोरी बफर को स्लाइसिंग और डाइसिंग का एक अलग तरीका है।

एक दृश्य में एक आकार, एक डेटा प्रकार (dtype), ऑफसेट और strides है। जहां संभव हो, एक numpy सरणी पर संचालन/reshaping संचालन सिर्फ मूल स्मृति बफर का एक दृश्य वापस कर देगा।

इसका मतलब है कि y = x.T या y = x[::2] जैसी चीजें किसी भी अतिरिक्त मेमोरी का उपयोग न करें, और x की प्रतियां न बनाएं।

तो, हम एक सरणी इस के समान है, तो:

import numpy as np 
x = np.array([1,2,3,4,5,6,7,8,9,10]) 

हम ऐसा करके यह नयी आकृति प्रदान कर सकता है या तो:

x = x.reshape((2, 5)) 

या

x.shape = (2, 5) 

पठनीयता के लिए, पहले विकल्प बेहतर है। वे (लगभग) बिल्कुल बराबर हैं, यद्यपि। कोई भी ऐसी प्रतिलिपि नहीं बनायेगा जो अधिक मेमोरी का उपयोग करेगा (पहले परिणामस्वरूप एक नया पायथन ऑब्जेक्ट होगा, लेकिन यह इस समय बिंदु के बगल में है।)।


Dtypes और विचारों

एक ही बात dtype पर लागू होता है। हम x.dtype या x.view(...) पर कॉल करके एक सरणी को एक अलग प्रकार के रूप में देख सकते हैं।

इस तरह बातें तो हम कर सकते हैं:

import numpy as np 
x = np.array([1,2,3], dtype=np.int) 

print 'The original array' 
print x 

print '\n...Viewed as unsigned 8-bit integers (notice the length change!)' 
y = x.view(np.uint8) 
print y 

print '\n...Doing the same thing by setting the dtype' 
x.dtype = np.uint8 
print x 

print '\n...And we can set the dtype again and go back to the original.' 
x.dtype = np.int 
print x 

कौन सा पैदावार:

The original array 
[1 2 3] 

...Viewed as unsigned 8-bit integers (notice the length change!) 
[1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0] 

...Doing the same thing by setting the dtype 
[1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0] 

...And we can set the dtype again and go back to the original. 
[1 2 3] 

ध्यान रखें, हालांकि, यह है कि आप निम्न स्तर के नियंत्रण दे रहा है जिस तरह से याद है कि अधिक बफर का अर्थ है।

उदाहरण के लिए:

import numpy as np 
x = np.arange(10, dtype=np.int) 

print 'An integer array:', x 
print 'But if we view it as a float:', x.view(np.float) 
print "...It's probably not what we expected..." 

यह पैदावार:

An integer array: [0 1 2 3 4 5 6 7 8 9] 
But if we view it as a float: [ 0.00000000e+000 4.94065646e-324 
    9.88131292e-324 1.48219694e-323 1.97626258e-323 
    2.47032823e-323 2.96439388e-323 3.45845952e-323 
    3.95252517e-323 4.44659081e-323] 
...It's probably not what we expected... 

तो, हम मूल स्मृति बफर के अंतर्निहित बिट्स तैरता के रूप में, की व्याख्या कर रहे हैं इस मामले में।

अगर हम फ्लोट्स के रूप में रिक्त इंक के साथ एक नई प्रतिलिपि बनाना चाहते हैं, तो हम x.astype (np.float) का उपयोग करेंगे।


परिसर नंबर

परिसर संख्या दो तैरता के रूप में जमा हो जाती है (दोनों सी, अजगर, और numpy में)। पहला असली हिस्सा है और दूसरा काल्पनिक हिस्सा है।

तो, अगर हम करते हैं:

import numpy as np 
x = np.array([0.5+1j, 1.0+2j, 3.0+0j]) 

हम वास्तविक (x.real) काल्पनिक (x.imag) भागों देख सकते हैं और। यदि हम इसे एक फ्लोट में परिवर्तित करते हैं, तो हमें काल्पनिक भाग को हटाने के बारे में एक चेतावनी मिलेगी, और हमें केवल वास्तविक भाग के साथ एक सरणी मिल जाएगी।

print x.real 
print x.astype(float) 

astype एक प्रतिलिपि बनाता है और नए प्रकार के मूल्यों बदल देता है।

हालांकि, अगर हम इस सरणी को फ्लोट के रूप में देखते हैं, तो हमें item1.real, item1.imag, item2.real, item2.imag, ... का अनुक्रम मिलेगा।

print x 
print x.view(float) 

पैदावार:

[ 0.5+1.j 1.0+2.j 3.0+0.j] 
[ 0.5 1. 1. 2. 3. 0. ] 

प्रत्येक जटिल संख्या अनिवार्य रूप से दो तैरता है, इसलिए यदि हम बदल कैसे numpy अंतर्निहित स्मृति बफर की व्याख्या, हम दो बार लंबाई की एक सरणी मिलता है।

उम्मीद है कि कि स्पष्ट बातें थोड़ा में मदद करता है ...

+0

ओएमजी, मैंने अपने कोड पर घंटे बिताए हैं। भगवान! इंगित करने के लिए धन्यवाद, क्या मैं पूछ सकता हूं, डिटेप भाग के अलावा, उसका बाकी कोड अभी भी सही है? मेरा मतलब है reshape भागों, धन्यवाद। – user1233157

+0

ठीक है, अगर आप 1 डी वेक्टर के रूप में सरणी के _copy_ को वापस करना चाहते हैं, तो बस 'array.flatten() 'पर कॉल करें। हालांकि, मेरा अद्यतन उत्तर देखें ... यदि 'सरणी' _always_ एक जटिल सरणी होने जा रहा था, तो कोड कुछ समझ में आता है, लेकिन यह भ्रामक रूप से दस्तावेज किया गया है, वैसे भी। –

+0

आपको बहुत बहुत धन्यवाद! इनपुट सरणी वास्तव में एक जटिल सरणी है, अब मैं समझ गया! हाहा, खुश – user1233157

2

इसके साथ गड़बड़ करने के बाद, मुझे लगता है कि मैन्युअल रूप से डिस्प्ले को डालने से आप जो चाहते हैं उसके बजाए कलाकारों को फिर से परिभाषित करते हैं। मतलब मुझे लगता है कि यह डेटा को एक रूप में परिवर्तित करने के बजाय सीधे फ्लोट के रूप में व्याख्या करता है। शायद आप aa = numpy.array(aa.map(float, aa)) आज़मा सकते हैं।

आगे स्पष्टीकरण: डेटा प्रकार का प्रकार है। documentation

एक डेटा प्रकार वस्तु (numpy.dtype वर्ग का एक उदाहरण) से शब्दशः के शब्दों में वर्णन करता है कि स्मृति एक सरणी आइटम के लिए इसी की निश्चित-आकार ब्लॉक में बाइट्स व्याख्या की जानी चाहिए।

इनट्स और फ्लोट्स में समान पैटर्न नहीं होते हैं, जिसका अर्थ है कि आप केवल एक int के लिए स्मृति को नहीं देख सकते हैं और यह एक ही संख्या होगी जब आप इसे फ्लोट के रूप में देखते हैं। फ्लैट 64 पर डाइट टाइप करके आप कंप्यूटर को फ्लोरिंग पॉइंट नंबरों में वास्तव में पूर्णांक संख्याओं को परिवर्तित करने के बजाय फ्लोट 64 के रूप में उस स्मृति को पढ़ने के लिए कह रहे हैं।

+0

आपको उत्तर देने के लिए बहुत बहुत धन्यवाद, और मैं वास्तव में कोड के एक पाइसक से सीख रहा हूं, जो एक सरणी को 1 आयामी वेक्टर में परिवर्तित करने का काम करना चाहिए, मैं बस उलझन में हूं कि यह मूल्य क्यों बदल गया। – user1233157

+0

मैंने अपना प्रश्न अपडेट किया है, जिस कोड को मैं प्रतिबिंबित कर रहा था उसे चिपकाया। धन्यवाद :) – user1233157

1

documentationdtypendarray की विशेषता बहुत उपयोगी नहीं है। आपके आउटपुट को देखते हुए ऐसा लगता है कि आठ 8 बाइट पूर्णांक के बफर को चार 8 बाइट फ्लोट के रूप में दोहराया जा रहा है।

लेकिन क्या आप चाहते हैं सरणी निर्माण में dtype निर्दिष्ट करने के लिए है:

array([1, 2, 3, 4, 5, 6, 7, 8], dtype="float64") 
+0

'dtype' के लिए प्रलेखन यहां है: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#arrays-dtypes इसके लायक होने के लिए। जो आपने लिंक किया है वह दस्तावेज डिप्टी क्लास भी नहीं है (जो यहां है: http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html#numpy.dtype), यह सिर्फ प्रलेखन है 'ndarray.dtype' के लिए, जो आपको अन्य दस्तावेज के लिए इंगित करता है। –

+0

मैंने अपना प्रश्न अपडेट किया है, क्या आप कृपया एक नज़र डालेंगे? बहुत बहुत धन्यवाद :) – user1233157

+0

ठीक है, मैंने मूल प्रश्न का उत्तर दिया, और आपने एक बहुत ही व्यापक उत्तर स्वीकार कर लिया है जिसमें सभी अड्डों को शामिल किया गया है। मुझे लगता है कि हमारा काम यहां किया गया है! –

5

इस तरह से dtype बदलने से, आप जिस तरह से स्मृति की एक निश्चित ब्लॉक में व्याख्या की जा रही है बदल रहे हैं।

उदाहरण:

>>> import numpy as np 
>>> a=np.array([1,0,0,0,0,0,0,0],dtype='int8') 
>>> a 
array([1, 0, 0, 0, 0, 0, 0, 0], dtype=int8) 
>>> a.dtype='int64' 
>>> a 
array([1]) 

नोट कैसे int8int64 करने से परिवर्तन एक 1 तत्व, 64 बिट सरणी में एक 8 तत्व, 8 बिट पूर्णांक सरणी बदल गया है,। हालांकि यह वही 8 बाइट ब्लॉक है। मूल iian मशीन के साथ मेरी i7 मशीन पर, बाइट पैटर्न int12 प्रारूप में 1 जैसा ही है।

बदलें की स्थिति 1:

>>> a=np.array([0,0,0,1,0,0,0,0],dtype='int8') 
>>> a.dtype='int64' 
>>> a 
array([16777216]) 

एक और उदाहरण:

>>> a=np.array([0,0,0,0,0,0,1,0],dtype='int32') 
>>> a.dtype='int64' 
>>> a 
array([0, 0, 0, 1]) 

बदलें 32 बाइट, 32 बिट सरणी में 1 की स्थिति:

>>> a=np.array([0,0,0,1,0,0,0,0],dtype='int32') 
>>> a.dtype='int64' 
>>> a 
array([   0, 4294967296,   0,   0]) 

यह बिट्स का एक ही ब्लॉक दोबारा परिभाषित किया गया है।

+0

हालांकि मैंने जो को टिक दिया है, और आपका जवाब बहुत अच्छा है, बहुत अच्छे उदाहरण! धन्यवाद। – user1233157

+0

@ उपयोगकर्ता 1233157: उनके उत्तर के लायक! आप अभी भी मुझे वोट दे सकते हैं :-) –

+0

अच्छा जवाब, वैसे भी! (+1) –

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