算术在dtype float'上的不同行为。并且'漂浮'

时间:2018-04-05 01:31:04

标签: python numpy

嗨,大家好我只是一个python的新手(即使在编程中)所以我的问题可能听起来很基本,但我很难理解这一点。

为什么算术上的选择性行为会浮动对象'?

import numpy as np

a = np.random.normal(size=10)
a = np.abs(a)
b = np.array(a, dtype=object)

np.square(a) # this works
np.square(b) # this works

np.sqrt(a) # this works
np.sqrt(b) # AttributeError: 'float' object has no attribute 'sqrt'

图片链接是我在本地jupyter笔记本中的运行结果:

jupyter笔记本运行结果 enter image description here

欣赏有用的见解!感谢

编辑050418 09:53 - 添加一个我认为类似问题的链接 Numpy AttributeError: 'float' object has no attribute 'exp'

3 个答案:

答案 0 :(得分:1)

@Warren指出square'代表'繁殖。我通过制作一个包含列表的对象数组来验证这一点:

In [524]: arr = np.array([np.arange(3), 3, [3,4]])
In [525]: np.square(arr)
TypeError: can't multiply sequence by non-int of type 'list'

square适用于数组的其余部分:

In [526]: np.square(arr[:2])
Out[526]: array([array([0, 1, 4]), 9], dtype=object)

sqrt并不适用于以下任何一项:

In [527]: np.sqrt(arr)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-527-b58949107b3d> in <module>()
----> 1 np.sqrt(arr)

AttributeError: 'numpy.ndarray' object has no attribute 'sqrt'

我可以让sqrt使用自定义类:

class Foo(float):
    def sqrt(self):
        return self**0.5

In [539]: arr = np.array([Foo(3), Foo(2)], object)
In [540]: np.square(arr)
Out[540]: array([9.0, 4.0], dtype=object)
In [541]: np.sqrt(arr)
Out[541]: array([1.7320508075688772, 1.4142135623730951], dtype=object)

答案 1 :(得分:0)

不确定这是否是原因,但我的猜测是:

如果您的对象是您自己的自制课程的实例怎么办? Numpy不能做任何其他事情,但希望你在课堂​​上定义了一个sqrt方法并让它完成工作。所以我假设它在这里做了什么,但在你的情况下你的对象是浮点数,虽然np.sqrt(some_random_float)有意义,但some_random_float.sqrt()并不是因为AttributeError: 'float' object has no attribute 'sqrt'

通常numpy是为数值计算而设计和优化的,而将它与通用dtype=object一起使用可能有时很方便,你不应该假设在这种情况下一切都会无缝运行...

答案 2 :(得分:0)

在Python中,一切都是对象。

操作符作为特殊方法在对象上实现(从方法名称中的__前缀可以看出,例如a + ba.__add__(b)的语法糖,或者它们是内置的别名将对象作为参数的函数(例如a ** b)是pow(a, b)的合成糖。通常,函数本身是对象上的特殊方法的别名(如iter(a)只返回{ {1}})。

Numpy添加了更多的语法糖,它实现了基于numpy对象类型的行为的函数。如上所述,具有dtype对象的numpy数组将操作符的实现推回到数组中元素的对象类型(所以基本上,a.__iter__()在语义上类似于np.square(a)这是真的评估为array = map(lambda x: x*x, array)

请注意,array = map(lambda x: x.__mult__(x), array)不作为内置函数存在(它可以从标准库中的sqrt模块或np的实现中导入,也可以使用math导入(实际上是{ {1}}),因此普通**0.5对象将没有实现它的方法。