2011-03-19 14 views
18

में अजीब कनवर्टिंग सरणी मेरे पास एक फ्लोट की एक सरणी है जिसे मैंने सामान्यीकृत किया है (यानी सरणी में सबसे बड़ी संख्या 1 है), और मैं इसे ग्राफ के लिए रंग सूचकांक के रूप में उपयोग करना चाहता था। ग्रेस्केल का उपयोग करने के लिए matplotlib का उपयोग करने में, इसे 0 और 1 के बीच स्ट्रिंग का उपयोग करने की आवश्यकता होती है, इसलिए मैं स्ट्रिंग्स की सरणी में फ्लोट की सरणी को कन्वर्ट करना चाहता था। मैं "astype ('str')" का उपयोग करके ऐसा करने का प्रयास कर रहा था, लेकिन ऐसा लगता है कि यह कुछ मान बनाते हैं जो मूल के समान (या यहां तक ​​कि करीब) नहीं हैं।फ्लोट से स्ट्रिंग्स

मुझे यह नोटिस है क्योंकि matplotlib सरणी में संख्या 8 खोजने के बारे में शिकायत करता है, जो अजीब है क्योंकि यह सामान्यीकृत था!

numpy.where(phis.astype('str').astype('float64') != phis) 

गैर खाली है:

संक्षेप में, मैं ऐसा है कि एक सरणी float64 की phis, है,। यह (उम्मीदवार रूप से naively) के रूप में परेशान है, यह numpy में एक बग प्रतीत होता है, क्या ऐसा कुछ भी है जिससे मैं इसे गलत कर सकता था?

संपादित करें: जांच के बाद यह स्ट्रिंग फ़ंक्शन उच्च परिशुद्धता फ्लोट को संभालने के तरीके के कारण होता है। (Robbles से के रूप में जवाब देने के) एक vectorized toString समारोह का उपयोग करना, यह भी मामला है, लैम्ब्डा समारोह है लेकिन यदि:

lambda x: "%.2f" % x 

तब रेखांकन काम करता है - कुरिओसेर और कुरिओसेर। (जाहिर है सरणियों लेकिन अब नहीं के बराबर हैं!)

उत्तर

29

आप थोड़ा उलझन में लगते हैं कि दृश्यों के पीछे कितनी संख्यात्मक सरणी काम करती हैं। सरणी में प्रत्येक आइटम समान आकार होना चाहिए।

एक फ्लोट का स्ट्रिंग प्रस्तुति इस तरह से काम नहीं करती है। उदाहरण के लिए, repr(1.3)'1.3' पैदा करता है, लेकिन repr(1.33)'1.3300000000000001' उत्पन्न करता है।

एक चल बिन्दु संख्या का एक सटीक स्ट्रिंग प्रतिनिधित्व एक चर लंबाई स्ट्रिंग पैदा करता है।

क्योंकि numpy arrays में तत्वों का समावेश होता है जो सभी समान आकार होते हैं, numpy आपको स्ट्रिंग सरणी का उपयोग करते समय सरणी के भीतर तारों की लंबाई निर्दिष्ट करने की आवश्यकता होती है।

आप x.astype('str') का उपयोग करते हैं, यह हमेशा चीजों लंबाई 1.

उदाहरण के लिए के तार की एक सरणी के लिए x = np.array(1.344566), x.astype('str') पैदावार '1' का उपयोग कर परिवर्तित कर देंगे,!

आपको अधिक स्पष्टीकरण और '|Sx' डाइट सिंटैक्स का उपयोग करने की आवश्यकता है, जहां x सरणी के प्रत्येक तत्व के लिए स्ट्रिंग की लंबाई है।

उदाहरण के लिए, x.astype('|S10') का उपयोग लंबाई 10

भी अच्छी बात के तार करने के लिए सरणी परिवर्तित करने के लिए, बस पूरी तरह तार के NumPy सरणी के प्रयोग से बचें। यह आमतौर पर एक बुरा विचार है, और कोई कारण नहीं है कि मैं आपकी समस्या के विवरण से पहले स्थान पर उपयोग कर सकूं ...

+0

तारों के numpy arrays का उपयोग करने का तर्क इसलिए था क्योंकि matplotlib को स्ट्रिंग्स के सही आकार के आकार की आवश्यकता होती है जो ग्रेस्केल का प्रतिनिधित्व करने के लिए 0 और 1 के बीच संख्याओं का प्रतिनिधित्व करती है (जो उस समय मैं चाहता था)।यह संख्याओं की सरणी को परिवर्तित करना सबसे आसान लग रहा था जो मेरे पास तारों की सरणी थी। मैं लंबाई जटिलता की उम्मीद नहीं कर रहा था। – VolatileStorm

+0

इस स्थिति में भी सहायक: 1.) फ़ाइल 2 से डेटा पढ़ें।) मान लें कि सभी प्रविष्टियां 'फ्लोट' हैं, हालांकि, कुछ 'नान' हैं। 3.) यदि सभी फ्लोट के रूप में पढ़े जाते हैं, तो सूची में 'डबल 64' चर' होंगे जो 'नान 'के रूप में दिखाई देते हैं लेकिन उन्हें' numpy.nan' 'के रूप में पहचाना नहीं जाता है।) उनको बदलने के लिए, मैंने सफलतापूर्वक उपयोग किया : 'अगर वी [-1] .astype (' | S3 ') ==' नैन ': वी [-1] = numpy.nan' – Schorsch

+0

आप np.genfromtxt का उपयोग कर सकते हैं और स्वचालित रूप से (अधिक या कम) से निपट सकते हैं। यदि आप उन्हें फ्लोट के रूप में उपयोग करना चाहते हैं तो फ़्लोट्स को तारों में परिवर्तित करना हमेशा एक बुरा विचार है। – Vincenzooo

12

आप numbers की एक सरणी है और आप strings की एक सरणी चाहते हैं, आप लिख सकते हैं:

strings = ["%.2f" % number for number in numbers] 

अपने नंबरों तैरता कर रहे हैं, सरणी होगा दो दशमलव के साथ तारों के समान संख्याओं के साथ एक सरणी हो।

>>> a = [1,2,3,4,5] 
>>> min_a, max_a = min(a), max(a) 
>>> a_normalized = [float(x-min_a)/(max_a-min_a) for x in a] 
>>> a_normalized 
[0.0, 0.25, 0.5, 0.75, 1.0] 
>>> a_strings = ["%.2f" % x for x in a_normalized] 
>>> a_strings 
['0.00', '0.25', '0.50', '0.75', '1.00'] 

सूचना यह भी numpy सरणियों के साथ काम करता है कि:

>>> a = numpy.array([0.0, 0.25, 0.75, 1.0]) 
>>> print ["%.2f" % x for x in a] 
['0.00', '0.25', '0.50', '0.75', '1.00'] 

यदि आप एक बहु-आयामी सरणी है ऐसा ही एक पद्धति इस्तेमाल किया जा सकता:

new_array = numpy.array(["%.2f" % x for x in old_array.reshape(old_array.size)]) 
new_array = new_array.reshape(old_array.shape) 

उदाहरण:

>>> x = numpy.array([[0,0.1,0.2],[0.3,0.4,0.5],[0.6, 0.7, 0.8]]) 
>>> y = numpy.array(["%.2f" % w for w in x.reshape(x.size)]) 
>>> y = y.reshape(x.shape) 
>>> print y 
[['0.00' '0.10' '0.20'] 
['0.30' '0.40' '0.50'] 
['0.60' '0.70' '0.80']] 

यदि आप Matplotlib example for the function you are using चेक करते हैं, तो आप देखेंगे कि वे एक समान पद्धति का उपयोग करते हैं: खाली मैट्रिक्स बनाएं और इसे इंटरपोलेशन विधि के साथ बनाए गए तारों से भरें। संदर्भित कोड के प्रासंगिक हिस्सा है:

colortuple = ('y', 'b') 
colors = np.empty(X.shape, dtype=str) 
for y in range(ylen): 
    for x in range(xlen): 
     colors[x, y] = colortuple[(x + y) % len(colortuple)] 

surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=colors, 
     linewidth=0, antialiased=False) 
+0

यह सवाल नहीं था। आप एक 'सूची' बना रहे हैं, वह एक numpy सरणी चाहता है। –

+0

मेरी माफी माँगती है कि यह स्पष्ट नहीं है, लेकिन मैं पाइथन सूचियों के साथ, numpy arrays से निपट रहा हूं। और क्या है, मेरी सरणी 2 आयामी है, इसलिए 1 डीआईएम सूची समझ काम नहीं करेगी। मुझे पूरी तरह से पता है कि मैं एक इंटरमीडिएट पायथन सूची बना सकता हूं और फिर एक numpy सरणी में परिवर्तित कर सकता हूं, लेकिन ऐसा लगता है कि उपरोक्त इस विधि को काम करना चाहिए और यह एक मध्यवर्ती सूची का उपयोग करने के लिए अतिरिक्त (धीमी) प्रोग्रामिंग है। – VolatileStorm

+0

यदि किसी ऑब्जेक्ट को पुन: चालू किया जा सकता है (जैसे सूची या एक numpy सरणी) यह सूची समझ का समर्थन करता है। इसे एक सूची (बतख टाइपिंग) होने की आवश्यकता नहीं है – Escualo

1

यह शायद आप क्या चाहते हैं की तुलना में धीमी है, लेकिन आप कर सकते हैं:

>>> tostring = vectorize(lambda x: str(x)) 
>>> numpy.where(tostring(phis).astype('float64') != phis) 
(array([], dtype=int64),) 

ऐसा लगता है कि यह मान बंद दौर जब यह str में धर्मान्तरित फ्लोट 64 से, लेकिन इस तरह आप रूपांतरण को कस्टमाइज़ कर सकते हैं हालांकि आपको पसंद है।

+0

यह या तो काम नहीं करता है, जो मुझे यह सुझाव देता है कि स्ट्रिंग के लिए बहुत छोटी संख्याओं का रूपांतरण विफल रहता है? अर्थात। सरणी में ऑर्डर 10^-30 की संख्या होती है। – VolatileStorm

+0

का मतलब है कि आपको एक अलग परिणाम मिलता है? मैंने इसे अभी एक छोटी 2 डी सरणी के साथ आजमाया और यह काम किया - शायद यह एक बग है ... – robbles

+0

ठीक है, अब मैं वास्तव में छोटी संख्या के साथ एक ही चीज़ देखता हूं। शायद यह एक सामान्य फ़्लोटिंग पॉइंट गणित मुद्दा है? – robbles

1

यदि मुख्य समस्या एक फ्लोट से स्ट्रिंग में कनवर्ट करते समय परिशुद्धता का नुकसान होता है, तो फ्लोट को decimal एस: http://docs.python.org/library/decimal.html में परिवर्तित करने का एक संभावित तरीका है।

पायथन 2 में।7 और उच्चतर आप सीधे एक फ्लोट को decimal ऑब्जेक्ट में परिवर्तित कर सकते हैं।

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