如何使用numpy数组对象的numpy数组执行numpy函数? [英] How to perform a numpy function with a numpy array of numpy array objects?

查看:108
本文介绍了如何使用numpy数组对象的numpy数组执行numpy函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有一个用于创建numpy数组对象的numpy数组的函数:

Let say we have a function for creating numpy arrays of numpy array objects:

randarr = lambda shape: np.random.randint(0, 10, shape)
get_numpy_array_obj = lambda shapes: \
    np.array([randarr(shape) for shape in shapes])

以及定义的数组大小:

shapes = [(2, 3), (3, 4), (4, 2)]

由于数组的形状不同,因此numpy将其他数组视为对象.

Because the shapes of the arrays is not the same, numpy treats the other arrays as objects.

现在,如果我们创建两个这样的数组

Now if we create two of these arrays

A = get_numpy_array_obj(shapes)
B = get_numpy_array_obj(shapes)

执行+,-,**等简单操作不是问题,例如:

doing simple operations like +, -, ** etc. is not a problem, e.g.:

C = A * B - (A + B)**2

当我想在tanh,exp等这些数组上应用numpy函数时,会发生问题.

The problem occurs when I want to apply a numpy function on these arrays like tanh, exp etc.

D = np.tanh(A)

这向我返回以下错误:

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

我可以像这样将函数逐个应用于每个数组

I could apply the function on each array one-by-one like this

D = np.array([np.tanh(a) for a in A])

我的想法是减少编写代码,提高可读性.

My idea was to write less code and more readable.

np.vectorize(np.tanh)(A)无法正常工作.这将返回:

Also np.vectorize(np.tanh)(A) was not working. This would return:

ValueError: setting an array element with a sequence.

还有另一种方法可以在numpy数组对象的数组上应用numpy函数吗?

Is there an other possible way to apply a numpy function on an array of numpy array objects?

推荐答案

In [99]: arr = np.array([np.ones(ij) for ij in [(1,3),(2,4),(3,2)]])
In [100]: arr
Out[100]: 
array([array([[1., 1., 1.]]),
       array([[1., 1., 1., 1.],
       [1., 1., 1., 1.]]),
       array([[1., 1.],
       [1., 1.],
       [1., 1.]])], dtype=object)

像'+'这样的运算符可以工作,因为数组具有相应的方法:

Operators like '+' work because arrays have the corresponding methods:

In [101]: arr[0].__add__
Out[101]: <method-wrapper '__add__' of numpy.ndarray object at 0xb64897a0>
In [102]: arr+arr
Out[102]: 
array([array([[2., 2., 2.]]),
       array([[2., 2., 2., 2.],
       [2., 2., 2., 2.]]),
       array([[2., 2.],
       [2., 2.],
       [2., 2.]])], dtype=object)

但是像np.tanh这样的函数没有数组方法.

But functions like np.tanh don't have array methods.

frompyfunc将数组的元素传递给函数,并返回对象dtype数组.通常这很痛苦,但是在这种情况下,这正是我们想要的:

frompyfunc passes elements of an array to your function and returns a object dtype array. Usually that's a pain, but in this case it's just what we want:

In [103]: np.frompyfunc(np.tan,1,1)(arr)
Out[103]: 
array([array([[1.55740772, 1.55740772, 1.55740772]]),
       array([[1.55740772, 1.55740772, 1.55740772, 1.55740772],
       [1.55740772, 1.55740772, 1.55740772, 1.55740772]]),
       array([[1.55740772, 1.55740772],
       [1.55740772, 1.55740772],
       [1.55740772, 1.55740772]])], dtype=object)

vectorize也使用frompyfunc,但尝试将结果转换为数字数组.我们可以通过指定otypes:

vectorize also uses frompyfunc but tries to convert the results to a numeric array. We can skip that by specifying an otypes:

In [104]: np.vectorize(np.tan,otypes='O')(arr)
Out[104]: 
array([array([[1.55740772, 1.55740772, 1.55740772]]),
       array([[1.55740772, 1.55740772, 1.55740772, 1.55740772],
       [1.55740772, 1.55740772, 1.55740772, 1.55740772]]),
       array([[1.55740772, 1.55740772],
       [1.55740772, 1.55740772],
       [1.55740772, 1.55740772]])], dtype=object)

对象数组的迭代速度介于列表迭代和数值数组迭代之间.它有一些阵列开销,但不是全部.元素是指针,就像列表中一样.

Iteration on object arrays is between list iteration and numeric array iteration in speed. It has some of the array overhead, but not all. The elements are pointers, just as in lists.

frompyfunc可能比显式迭代快一点(最多2倍). vectorize有点慢,因为它有一些开销.这些功能的最大优点是它们可以处理广播.自己安排时间,看看是否有帮助.

frompyfunc can be a bit faster (up to 2x) than explicit iteration. vectorize is a bit slower because it has some overhead. The big advantage of these functions is that they handle broadcasting. Do your own timings to see if they help.

这篇关于如何使用numpy数组对象的numpy数组执行numpy函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆