【问题标题】:Error "TypeError: type numpy.ndarray doesn't define __round__ method"错误“TypeError:类型 numpy.ndarray 未定义 __round__ 方法”
【发布时间】:2019-08-28 23:56:46
【问题描述】:
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. 

为什么总是报这个错误:

  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

如果我不使用“round”,它会正确打印小数。这个“圆”应该是 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] 

【问题讨论】:

  • 我认为predictions 是一个二维数组,形状可能为 (11,1)。

标签: python numpy


【解决方案1】:

TypeError: type numpy.ndarray 没有定义 round 方法

您尝试将 round 应用于 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]

【讨论】:

  • 但是'round'不是应用于单个十进制'x',它不是一个数组吗?
  • 你确定 x 是一位小数吗?打印出来证明一下。
  • "predictions" 是一个 numpy 数组,但 'x' 是单个值。
  • 请看我的补充。
  • 注意[ 和]。 x 是包含一个元素的 numpy 数组。
【解决方案2】:

model 是什么?来自什么模块?看起来predictions 是一个二维数组。 predictions.shape 是什么?该错误表明[x for x in predictions] 中的x 是一个数组。它可能是一个单元素数组,但它绝不是一个数组。您可以尝试[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 版本文档。

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

从您的上一次打印中,我可以将您的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 列的二维数组。

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

【讨论】:

    【解决方案3】:

    我在尝试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 参数。但输出的值是正确的。因此将列表的每个元素转换为浮点类型将显示与教程相同的正确输出。

    我的机器是Linux Mint 17.3(ubuntu 14.04) x64,python解释器是python 3.5.2、anaconda3(4.1.1)、numpy 1.11.2

    【讨论】:

    • 你能解释一下吗?
    • 现在工作了,它显示的结果类似于 1,0,0,1,1,.... 而不是 array([0.5168],dtype=float32)
    【解决方案4】:

    您正在使用一个函数,该函数使用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=' ')
    

    【讨论】:

    • 'x' 是单个数字。
    • 请看我的补充。
    • @user697911 请看我的评论,因为 numpy 有一种奇怪的方式来制作列表。这实际上应该解开该值,以便您可以舍入。
    【解决方案5】:

    这也让我发疯了。我已经存储了一个类型为&lt;class 'scipy.interpolate.interpolate.interp1d'&gt; 的scipy 函数的引用。这将返回包含单个浮点数的 &lt;class 'numpy.ndarray'&gt; 类型的单个值。我以为这实际上是一个浮点数,它通过我的库代码传播回来,直到 round 产生上述相同的错误。

    这是一个调试调用堆栈以检查每个函数返回后传递的实际类型的案例。然后我按照result = float(interp1d_reference(x)) 的行从我的原始函数调用中转换返回值。然后我的代码表现得像我预期/想要的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      • 2018-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多