在同时包含数字和对象的数组上使用NumPy函数

时间:2019-02-15 16:06:05

标签: python numpy

我有一个类似数字的类,其中实现了sqrtexp等方法,以便当NumPy函数位于ndarray中时,将在它们上广播。 / p>

class A:
    def sqrt(self):
        return 1.414

这在以下数组中非常有效:

import numpy as np
print(np.sqrt([A(), A()]))  # [1.414 1.414]

很显然,sqrt也适用于纯数字:

print(np.sqrt([4, 9]))  # [2. 3.]

但是,当数字和对象混合在一起时,这不起作用:

print(np.sqrt([4, A()]))

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-38-0c4201337685> in <module>()
----> 1 print(np.sqrt([4, A()]))

AttributeError: 'int' object has no attribute 'sqrt'

之所以会这样,是因为异构数组的dtypeobject,并且numpy函数通过在每个对象上调用相同名称的方法来广播,但是数字没有使用这些名称的方法。

我该如何解决?

1 个答案:

答案 0 :(得分:1)

不确定效率,但是可以通过使用mapisinstance创建的布尔索引来解决,然后将其应用于同一切片,并更改操作的元素类型不是A类,因此无法使用numpy方法。

ar = np.array([4, A(), A(), 9.])
ar_t = np.array(list(map(lambda x: isinstance(x, A), ar)))

ar[~ar_t] = np.sqrt(ar[~ar_t].astype(float)) 
ar[ar_t] = np.sqrt(ar[ar_t])

print(ar)
# array([2.0, 1.414, 1.414, 3.0], dtype=object)

注意:在astype中,我使用了float,但不确定它是否可以满足您的要求