gpt4 book ai didi

python - 如何在不使用 `quantities.Quantity` 对其进行子类化的情况下添加 `__array__` 行为?

转载 作者:太空狗 更新时间:2023-10-30 02:13:20 25 4
gpt4 key购买 nike

quantities.Quantitynumpy.ndarray 的子类,用于处理物理量的算术和转换。我如何在不对其进行子类化的情况下使用它的算术?下面的方法使用了 __array__-method——但只工作了 80%,正如你在最后看到的那样:

class Numeric(object):
def __init__(self, signal):
self.signal = signal
self._dimensionality = self.signal._dimensionality
self.dimensionality = self.signal.dimensionality
def __array__(self):
return self.signal
def __mul__(self, obj):
return self.signal.__mul__(obj)
def __rmul__(self, obj):
return self.signal.__rmul__(obj)

有了这个我可以做到:

import quantities as pq
import numpy as np

num = Numeric(pq.Quantity([1,2,3], 'mV'))
q = pq.Quantity([2,3,4], 'mV')
n = np.array([3,4,5])

以下所有操作都返回正确的单位——除了最后一个,那里缺少单位:

print num * num
# [1 4 9] mV**2
print num * q
# [ 2 6 12] mV**2
print num * n
# [ 3 8 15] mV
print q * num
# [ 2 6 12] mV**2
print n * num
# [ 3 8 15] <------- no unit!

知道要修复什么才能保持正确的单位吗?

编辑:算术运算的返回类型/值应等同于:

  • num.signal * num.signal
  • num.signal * q
  • num.signal * n
  • q * num.signal
  • n * num.signal # 这行不通

最佳答案

当 Python 看到 x * y 时会发生以下情况:

  • 如果 yx 的子类 --> y.__rmul__(x) 被调用

否则:

  • x.__mul__(y) 被调用

IF x.__mul__(y) 返回 NotImplemented(不同于 raise NotImplementedError

  • y.__rmul__(x) 被调用

因此,有两种方法可以调用 __rmul__——子类 ndarray,或者让 ndarray 不能与 数字

您无法子类化,显然 ndarray 很乐意使用 Numeric,所以 。 . .

值得庆幸的是,numpy 人员已经为这种情况做好了准备——答案就在 __array_wrap__ 方法中:

def __array_wrap__(self, out_arr, context=None):
return type(self.signal)(out_arr, self.dimensionality)

我们使用原始的 signal 类以及原始维度为新的 Numeric 对象创建新的信号。

整个位看起来像这样:

import quantities as pq
import numpy as np

class Numeric(object):
def __init__(self, signal):
self.signal = signal
self.dimensionality = self.signal.dimensionality
self._dimensionality = self.signal._dimensionality
def __array__(self):
return self.signal
def __array_wrap__(self, out_arr, context=None):
return type(self.signal)(out_arr, self.dimensionality)
def __mul__(self, obj):
return self.signal.__mul__(obj)
def __rmul__(self, obj):
return self.signal.__rmul__(obj)


num = Numeric(pq.Quantity([1,2,3], 'mV'))
q = pq.Quantity([2,3,4], 'mV')
n = np.array([3,4,5])

t = num * num
print type(t), t
t = num * q
print type(t), t
t = num * n
print type(t), t
t = q * num
print type(t), t
t = n * num
print type(t), t

运行时:

<class 'quantities.quantity.Quantity'> [1 4 9] mV**2
<class 'quantities.quantity.Quantity'> [ 2 6 12] mV**2
<class 'quantities.quantity.Quantity'> [ 3 8 15] mV
<class 'quantities.quantity.Quantity'> [ 2 6 12] mV**2
<class 'quantities.quantity.Quantity'> [ 3 8 15] mV

关于python - 如何在不使用 `quantities.Quantity` 对其进行子类化的情况下添加 `__array__` 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9535948/

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