【问题标题】:How to use numpy.frompyfunc to return an array of elements instead of array of arrays?如何使用 numpy.frompyfunc 返回元素数组而不是数组数组?
【发布时间】:2015-06-23 22:21:10
【问题描述】:

我正在使用 SHTOOLS 包中的 PLegendre 函数。它返回一个特定参数的勒让德多项式数组。 PLegendre(lmax,x) 返回 Legendre 多项式 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.        ]])

但是.. 有没有办法直接解决这个问题,而不必对数组进行切片?

【问题讨论】:

    标签: python arrays numpy numpy-ufunc


    【解决方案1】:

    我认为它不能直接完成,正如 here 已经指出的那样,np.vectorize 的作用几乎相同。请注意,您的代码并不比使用np.frompyfunc 的普通for 循环更快......代码看起来更好。

    但是,您可以使用 np.vstack 而不是列表理解

    a = legendre(3,np.linspace(0,1,4))
    np.vstack(a)
    

    【讨论】:

      【解决方案2】:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 1970-01-01
        • 2021-10-04
        • 1970-01-01
        • 2016-08-20
        • 1970-01-01
        • 2016-06-27
        相关资源
        最近更新 更多