如何使用 numpy.frompyfunc 到 return 元素数组而不是数组数组?
How to use numpy.frompyfunc to return an array of elements instead of array of arrays?
我正在使用 SHTOOLS 包中的 PLegendre 函数。它 returns 特定参数的勒让德多项式数组。 PLegendre(lmax,x) returns 勒让德多项式数组 P_0(x) 到 P_lmax(x)。它是这样工作的:
In [1]: from pyshtools import PLegendre
loading shtools documentation
In [2]: import numpy as np
In [3]: PLegendre(3,0.5)
Out[3]: array([ 1. , 0.5 , -0.125 , -0.4375])
我想传递一个数组作为参数,所以我使用 frompyfunc。
In [4]: legendre=np.frompyfunc(PLegendre,2,1)
In [5]: legendre(3,np.linspace(0,1,4))
Out[5]:
array([array([ 1. , 0. , -0.5, -0. ]),
array([ 1. , 0.33333333, -0.33333333, -0.40740741]),
array([ 1. , 0.66666667, 0.16666667, -0.25925926]),
array([ 1., 1., 1., 1.])], dtype=object)
输出是一个数组数组。我知道我可以通过对数组进行切片来创建一个元素数组。
In [6]: a=legendre(3,np.linspace(0,1,4))
In [7]: array([a[i][:] for i in xrange(4)])
Out[7]:
array([[ 1. , 0. , -0.5 , -0. ],
[ 1. , 0.33333333, -0.33333333, -0.40740741],
[ 1. , 0.66666667, 0.16666667, -0.25925926],
[ 1. , 1. , 1. , 1. ]])
但是..有没有办法直接做到这一点,而不必对数组的数组进行切片?
我认为它不能像已经指出的那样直接完成 here 在 np.vectorize
的情况下几乎做同样的事情。请注意,您的代码并不比使用 np.frompyfunc
的普通 for
循环更快……代码看起来更好。
但是,您可以使用 np.vstack
而不是列表理解
a = legendre(3,np.linspace(0,1,4))
np.vstack(a)
np.frompyfunc
已编译,因此我必须深入研究源代码才能确切了解它在做什么。但它似乎假设 func 输出是一个(难以理解的)Python 对象。
foo1 = np.frompyfunc(np.arange,1,1)
foo2 = np.vectorize(np.arange,otypes='O')
这 2 个函数产生相同的输出,但 foo1
更快。
foo1(np.arange(4))
生成不同大小的数组
array([array([], dtype=int32), array([0]), array([0, 1]), array([0, 1, 2])], dtype=object)
其中foo1(np.ones((4,))
都是一样的,理论上可以叠加。
在循环期间或之后,没有尝试测试对象是否为数组(或列表)以及它们是否可以组合成一个更高维的数组。
plonser's
使用 vstack
是个好主意。事实上 frompyfunc
加 vstack
比更常见的列表理解加 vstack
.
更快
In [54]: timeit np.vstack([np.arange(i) for i in 10*np.ones((10,))])
10000 loops, best of 3: 169 µs per loop
In [55]: timeit np.vstack(foo1(10*np.ones((10,))))
10000 loops, best of 3: 127 µs per loop
我正在使用 SHTOOLS 包中的 PLegendre 函数。它 returns 特定参数的勒让德多项式数组。 PLegendre(lmax,x) returns 勒让德多项式数组 P_0(x) 到 P_lmax(x)。它是这样工作的:
In [1]: from pyshtools import PLegendre
loading shtools documentation
In [2]: import numpy as np
In [3]: PLegendre(3,0.5)
Out[3]: array([ 1. , 0.5 , -0.125 , -0.4375])
我想传递一个数组作为参数,所以我使用 frompyfunc。
In [4]: legendre=np.frompyfunc(PLegendre,2,1)
In [5]: legendre(3,np.linspace(0,1,4))
Out[5]:
array([array([ 1. , 0. , -0.5, -0. ]),
array([ 1. , 0.33333333, -0.33333333, -0.40740741]),
array([ 1. , 0.66666667, 0.16666667, -0.25925926]),
array([ 1., 1., 1., 1.])], dtype=object)
输出是一个数组数组。我知道我可以通过对数组进行切片来创建一个元素数组。
In [6]: a=legendre(3,np.linspace(0,1,4))
In [7]: array([a[i][:] for i in xrange(4)])
Out[7]:
array([[ 1. , 0. , -0.5 , -0. ],
[ 1. , 0.33333333, -0.33333333, -0.40740741],
[ 1. , 0.66666667, 0.16666667, -0.25925926],
[ 1. , 1. , 1. , 1. ]])
但是..有没有办法直接做到这一点,而不必对数组的数组进行切片?
我认为它不能像已经指出的那样直接完成 here 在 np.vectorize
的情况下几乎做同样的事情。请注意,您的代码并不比使用 np.frompyfunc
的普通 for
循环更快……代码看起来更好。
但是,您可以使用 np.vstack
而不是列表理解
a = legendre(3,np.linspace(0,1,4))
np.vstack(a)
np.frompyfunc
已编译,因此我必须深入研究源代码才能确切了解它在做什么。但它似乎假设 func 输出是一个(难以理解的)Python 对象。
foo1 = np.frompyfunc(np.arange,1,1)
foo2 = np.vectorize(np.arange,otypes='O')
这 2 个函数产生相同的输出,但 foo1
更快。
foo1(np.arange(4))
生成不同大小的数组
array([array([], dtype=int32), array([0]), array([0, 1]), array([0, 1, 2])], dtype=object)
其中foo1(np.ones((4,))
都是一样的,理论上可以叠加。
在循环期间或之后,没有尝试测试对象是否为数组(或列表)以及它们是否可以组合成一个更高维的数组。
plonser's
使用 vstack
是个好主意。事实上 frompyfunc
加 vstack
比更常见的列表理解加 vstack
.
In [54]: timeit np.vstack([np.arange(i) for i in 10*np.ones((10,))])
10000 loops, best of 3: 169 µs per loop
In [55]: timeit np.vstack(foo1(10*np.ones((10,))))
10000 loops, best of 3: 127 µs per loop