2016-04-17 51 views
8

दिखा केवल लंबाई -1 सरणियों अजगर scalars में बदला जा सकता मैं ऐसे पायथन कोड है:लेखन त्रुटि: जबकि साजिश

import numpy as np 
import matplotlib.pyplot as plt 

def f(x): 
    return np.int(x) 

x = np.arange(1, 15.1, 0.1) 
plt.plot(x, f(x)) 
plt.show() 

और ऐसे त्रुटि:

TypeError: only length-1 arrays can be converted to Python scalars 

मैं इसे कैसे ठीक कर सकते हैं?

उत्तर

10

त्रुटि "केवल लंबाई -1 सरणियों अजगर scalars में बदला जा सकता" जब समारोह एकल मान उम्मीद उठाया है, लेकिन आप एक सरणी के बजाय गुजरती हैं।

यदि आप np.int के कॉल हस्ताक्षर को देखते हैं, तो आप देखेंगे कि यह एक मान को स्वीकार करता है, न कि सरणी। सामान्य तौर पर, यदि आप एक समारोह है कि एक सरणी में प्रत्येक तत्व के लिए एक एकल तत्व को स्वीकार करता है लागू करना चाहते हैं, तो आप np.vectorize उपयोग कर सकते हैं:

import numpy as np 
import matplotlib.pyplot as plt 

def f(x): 
    return np.int(x) 
f2 = np.vectorize(f) 
x = np.arange(1, 15.1, 0.1) 
plt.plot(x, f2(x)) 
plt.show() 

आप f (x) और बस पारित np.int की परिभाषा को छोड़ सकते हैं वेक्टरटाइज़ फ़ंक्शन के लिए: f2 = np.vectorize(np.int)

ध्यान दें कि np.vectorize केवल एक सुविधा कार्य है और मूल रूप से लूप के लिए है। यह बड़े सरणी पर अक्षम होगा। जब भी आपको संभावना हो, वास्तव में वेक्टरीकृत फ़ंक्शंस या विधियों का उपयोग करें (जैसे astype(int)@FFT suggests)।

+1

मैंने आपको जवाब में हराया, लेकिन आपका निश्चित रूप से अधिक सुरुचिपूर्ण है :) – roganjosh

+0

आह हाँ, np.vectorize मूल रूप से एक लूप भी है लेकिन यह मुझे लगता है कि यह बेहतर लगता है। :) – ayhan

+0

क्लीनर और मैं भी तेज़ी से कल्पना करता हूं (मुझे परीक्षण करना चाहिए)। मुझे अभी भी इस तरह की चीजों के लिए numpy की जटिलताओं को सीखना है :) – roganjosh

1

x के लिए मुद्रित किए गए नोट पर ध्यान दें। आप एक सरणी में मूल रूप से केवल एक सूची (मूल रूप से केवल एक सूची) को बदलने की कोशिश कर रहे हैं। length-1 एक एकल संख्या का सरणी होगा, जो मुझे लगता है कि numpy सिर्फ एक फ्लोट के रूप में व्यवहार करता है। आप यह कर सकते हैं, लेकिन यह एक पूरी तरह से numpy समाधान नहीं है।

संपादित करें: मैं कुछ हफ्ते पहले एक पोस्ट में शामिल था जहां numpy की अपेक्षा की तुलना में एक ऑपरेशन धीमा था और मुझे एहसास हुआ कि मैं एक डिफ़ॉल्ट मानसिकता में गिर गया था कि numpy हमेशा गति के लिए जाने का तरीका था। चूंकि मेरा जवाब ऐहान के रूप में साफ नहीं था, मैंने सोचा कि मैं इस स्पेस का उपयोग यह दिखाने के लिए करूंगा कि यह एक और उदाहरण है कि vectorize पाइथन में एक सूची बनाने से लगभग 10% धीमी है। मुझे समझाने के लिए पर्याप्त जानकारी नहीं है कि यह मामला क्यों है लेकिन शायद कोई और करता है?

import numpy as np 
import matplotlib.pyplot as plt 
import datetime 

time_start = datetime.datetime.now() 

# My original answer 
def f(x): 
    rebuilt_to_plot = [] 
    for num in x: 
     rebuilt_to_plot.append(np.int(num)) 
    return rebuilt_to_plot 

for t in range(10000): 
    x = np.arange(1, 15.1, 0.1) 
    plt.plot(x, f(x)) 

time_end = datetime.datetime.now() 

# Answer by ayhan 
def f_1(x): 
    return np.int(x) 

for t in range(10000): 
    f2 = np.vectorize(f_1) 
    x = np.arange(1, 15.1, 0.1) 
    plt.plot(x, f2(x)) 

time_end_2 = datetime.datetime.now() 

print time_end - time_start 
print time_end_2 - time_end 
संबंधित मुद्दे