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

drh*_*gen 5 python numpy

我有相同数量级的,我已经实现了sqrt,exp等方法,使NumPy的功能将他们播出时,他们在ndarray秒.

class A:
    def sqrt(self):
        return 1.414
Run Code Online (Sandbox Code Playgroud)

这个工作完美地在这些:

import numpy as np
print(np.sqrt([A(), A()]))  # [1.414 1.414]
Run Code Online (Sandbox Code Playgroud)

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

print(np.sqrt([4, 9]))  # [2. 3.]
Run Code Online (Sandbox Code Playgroud)

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

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'
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为dtype异构数组是object通过在每个对象上调用同名方法来广播numpy函数,但是数字没有具有这些名称的方法.

我该如何解决这个问题?

Ben*_*n.T 1

不确定效率,但作为解决方法,您可以使用使用 和 创建的布尔索引,map然后isinstance对两个切片应用相同的操作,更改不属于类的元素的类型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)
Run Code Online (Sandbox Code Playgroud)

注意:在 中astype,我使用了float,但不确定它是否适合您的要求