2016-12-25 476 views
2
import numpy 

...... 

# Prediction 
predictions = model.predict(X_test) 
# round predictions 
rounded = [round(x) for x in predictions] 
print(rounded) 

"predictions" is a list of decimals between [0,1] with sigmoid output. 

爲什麼總是報告這個錯誤:錯誤「類型錯誤:類型numpy.ndarray沒有定義__round__法」

File "/home/abigail/workspace/ml/src/network.py", line 41, in <listcomp> 
    rounded = [round(x) for x in predictions] 
TypeError: type numpy.ndarray doesn't define __round__ method 

如果我不使用「圓」,它打印小數正確。這個「輪」應該是Python內置函數。爲什麼它與numpy有什麼關係?

編輯:

for x in predictions: 
    print(x, end=' ') 

輸出是:

[ 0.79361773] [ 0.10443521] [ 0.90862566] [ 0.10312044] [ 0.80714297] 
[ 0.23282401] [ 0.1730803] [ 0.55674052] [ 0.94095331] [ 0.11699325] 
[ 0.1609294] 
+0

我認爲'predictions'是一個二維數組,可能與形狀(11,1)。 – hpaulj

回答

2

什麼是model?從什麼模塊?它看起來像predictions是一個二維數組。什麼是predictions.shape?該錯誤表明在[x for x in predictions]是一個數組。它可能是一個單一的元素數組,但它永遠不會是一個數組。您可以嘗試[x.shape for x in predictions]查看每個元素(行)predictions的形狀。

我沒有太多機會使用round,但顯然Python函數代表作用的.__round__方法(多+委託給__add__)。

In [932]: round? 
Docstring: 
round(number[, ndigits]) -> number 

Round a number to a given precision in decimal digits (default 0 digits). 
This returns an int when called with one argument, otherwise the 
same type as the number. ndigits may be negative. 
Type:  builtin_function_or_method 
In [933]: x=12.34 
In [934]: x.__round__? 
Docstring: 
Return the Integral closest to x, rounding half toward even. 
When an argument is passed, work like built-in round(x, ndigits). 
Type:  builtin_function_or_method 
In [935]: y=12 
In [936]: y.__round__? 
Docstring: 
Rounding an Integral returns itself. 
Rounding with an ndigits argument also returns an integer. 
Type:  builtin_function_or_method 

Python整數與python浮點數有不同的實現。

Python列表和字符串沒有爲此定義,所以round([1,2,3])將返回一個AttributeError: 'list' object has no attribute '__round__'

同樣爲ndarray。但是numpy定義了np.round函數,而numpy數組具有.round方法。

In [942]: np.array([1.23,3,34.34]).round() 
Out[942]: array([ 1., 3., 34.]) 
In [943]: np.round(np.array([1.23,3,34.34])) 
Out[943]: array([ 1., 3., 34.]) 

help(np.around)給出的numpy的版本(S)的最大文檔。

===================

從你最後一次打印,我可以重建你的predictions的一部分:

In [955]: arr = np.array([[ 0.79361773], [ 0.10443521], [ 0.90862566]]) 
In [956]: arr 
Out[956]: 
array([[ 0.79361773], 
     [ 0.10443521], 
     [ 0.90862566]]) 
In [957]: for x in arr: 
    ...:  print(x, end=' ') 
    ...:  
[ 0.79361773] [ 0.10443521] [ 0.90862566] 

arr.shape(3,1) - 具有1列的2d陣列。

np.round正常工作,而無需迭代:

In [958]: np.round(arr) 
Out[958]: 
array([[ 1.], 
     [ 0.], 
     [ 1.]]) 

迭代產生的錯誤。

In [959]: [round(x) for x in arr]  
TypeError: type numpy.ndarray doesn't define __round__ method 
+0

讓我先閱讀。 – user697911

1

您使用使用Numpy存儲值的功能。它不是一個常規的Python列表,它實際上是一個Numpy數組。這通常是因爲通過機器學習,Numpy與Python中的普通列表相比,在存儲海量數據方面做得更好。您可以參考下面的文檔轉換爲常規列表,然後可以大跳理解:

https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.tolist.html

編輯:

會發生什麼,如果你嘗試:

for x in predictions: 
    for y in x.: 
    print(y, end=' ') 
+0

'x'是單個數字。 – user697911

+0

請參閱我的補充。 – user697911

+0

@ user697911請看我的評論,因爲numpy有一個奇怪的列表清單方式。這實際上應該打開這個值,以便你可以四捨五入。 – rb612

2

TypeError: type numpy.ndarray doesn't define round method

您試過申請輪到numpy.ndarray。顯然,這不被支持。

嘗試此,使用numpy.round

rounded = [numpy.round(x) for x in predictions] 

x是numpy的陣列。您也可以試試這個:

rounded = [round(y) for y in x for x in predictions] 
+0

但不是'圓'適用於一個小數'x',這不是一個數組? – user697911

+0

你確定x是單精度小數嗎?打印它來證明它。 – gzc

+0

「預測」是一個numpy數組,但'x'是單個值。 – user697911

0

我在嘗試教程Keras時遇到了同樣的錯誤。

起初,我試圖

rounded = [numpy.round(x) for x in predictions] 

,但它顯示的結果是這樣的:

[array([1.], dtype=float32), array([0.],dtype=float32), ...] 

然後我嘗試這樣做:

rounded = [float(numpy.round(x)) for x in predictions] 

它顯示正確的輸出。

我認爲「numpy.round(x)」返回ndarray的列表,並且包含dtype參數。但輸出與數值正確。因此,將列表中的每個元素轉換爲float類型將顯示與教程相同的正確輸出。

我的機器是Linux Mint的17.3(ubuntu的14.04)x64和python解釋是蟒3.5.2,anaconda3(4.1.1),numpy的1.11.2

+0

你能提供一些解釋嗎? – thumbtackthief