gpt4 book ai didi

python - 带有 __add__ 的自定义类以添加 NumPy 数组

转载 作者:行者123 更新时间:2023-12-03 09:38:05 25 4
gpt4 key购买 nike

我有一个自定义类实现 __add__ 和 __radd__ 作为

import numpy

class Foo(object):

def __init__(self, val):
self.val = val

def __add__(self, other):
print('__add__')
print('type self = %s' % type(self))
print('type other = %s' % type(other))
return self.val + other

def __radd__(self, other):
print('__radd__')
print('type self = %s' % type(self))
print('type other = %s' % type(other))
return other + self.val

我首先测试 __add__
r1 = Foo(numpy.arange(3)) + numpy.arange(3,6)
print('type results = %s' % type(r1))
print('result = {}'.format(r1))

它导致了预期的结果
>>> __add__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'numpy.ndarray'>
>>> type results = <type 'numpy.ndarray'>
>>> result = [3 5 7]

但是,测试 __radd__
r2 = numpy.arange(3) + Foo(numpy.arange(3,6))
print('type results = %s' % type(r2))
print('result = {}'.format(r2))

我得到
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> type results = <type 'numpy.ndarray'>
>>> result = [array([3, 4, 5]) array([4, 5, 6]) array([5, 6, 7])]

这对我来说没有任何意义。 NumPy 是否为任意对象重载 __add__,然后优先于我的 __radd__?如果是,他们为什么要这样做?此外,我该如何避免这种情况,我真的希望能够在左侧添加带有 NumPy 数组的自定义类。谢谢。

最佳答案

这被评论隐藏了,但应该是答案。

默认情况下,Numpy 操作基于每个元素对任意对象进行操作,然后尝试按元素执行操作(根据广播规则)。

例如,这意味着给定

class N:
def __init__(self, x):
self.x = x

def __add__(self, other):
return self.x + other

def __radd__(self, other):
return other + self.x

由于 Python 操作符解析
N(3) + np.array([1, 2, 3])

会到上面 __add__N(3)和整个数组为 other一次,然后执行常规的 Numpy 加法。

另一方面
np.array([1, 2, 3]) + N(3)

将成功进入 Numpy 的 ufuncs(在本例中为运算符),因为它们将任意对象作为“其他”,然后尝试依次执行:
1 + N(3)
2 + N(3)
3 + N(3)

这意味着 __add__以上会 被调用 3 次而不是一次,每个元素调用一次 ,显着减慢操作。要禁用此行为,并使 Numpy养一个 NotImplementedError当服用 N对象从而允许 RHS 过载 radd要接管,请将以下内容添加到您的类(class)正文中:
class N:
...
__numpy_ufunc__ = None # Numpy up to 13.0
__array_ufunc__ = None # Numpy 13.0 and above

如果向后兼容性不是问题,则只需要第二个。

关于python - 带有 __add__ 的自定义类以添加 NumPy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45947152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com