如何有效地将"vectorize"函数(Numpy库)系统化 - Python



正如标题所示,我想有效地cythonize numpy.vectorize函数,其核心是简化下面的这一部分(完整的函数太长了,不能发布,但大部分时间都花在这里):

    def func(*vargs):
        for _n, _i in enumerate(inds):
            the_args[_i] = vargs[_n]
        kwargs.update(zip(names, vargs[len(inds):]))
        return self.pyfunc(*the_args, **kwargs)

我已经阅读了这些指南(http://cython.readthedocs.io/en/latest/src/tutorial/numpy.html和http://pandas.pydata.org/pandas-docs/stable/enhancingperf.html),它们非常有用,但是我的C知识太窄,无法使用它们的一小部分潜力。

你会怎么做?[Python 3.5.1, cyth0.25 a, Numpy 1.10.4]

您显示的函数只是处理kwargs的一点舞蹈。请注意vectorize.__call__中该块头部的注释。对于更简单的参数,它只设置func = self.pyfunc

实际工作在最后一行完成:

self._vectorize_call(func=func, args=vargs)

,

outputs = ufunc(*inputs)
< return dtype conversion >

ufunc在大多数情况下是frompyfunc(func, len(args), nout)

所以剥去所有Python的封面,它归结为

np.frompyfunc(your_func, n, m)(args)

frompyfunc是一个编译函数。我怀疑该函数使用nditer (c版本)来广播参数,并将值作为标量提供给your_func。我在最近的另一个SO中讨论了nditercython的使用。

总而言之,只要your_func是一个不可渗透的(或通用的)python函数,cython就无法改进这一点。迭代已经在编译后的代码中被处理。

最新更新