如何有效地cython化" vectorize"函数(numpy库) - python

时间:2016-09-02 13:09:56

标签: python numpy vectorization cython

作为标题的补充,我希望有效地对numpy.vectorize函数进行cython化,这对于核心,正在简单地完成这一部分(完整的函数太长而不能发布但是大多数时间花在这里):

    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.htmlhttp://pandas.pydata.org/pandas-docs/stable/enhancingperf.html),这些指南非常有用,但我对C的了解太过狭窄,无法将它们用于潜在的一小部分。

你会怎么做? [Python 3.5.1,Cython 0.25a,Numpy 1.10.4]

1 个答案:

答案 0 :(得分:2)

你展示的功能只是有点跳舞来处理from itertools import groupby ips = ['10.0.0.1', '10.0.0.2', '10.0.10.3', '10.0.0.4', '10.0.0.5'] def get_subnet(ip): return '.'.join(ip.split('.')[:3]) groups = {} # group ips by subnet for k, g in groupby(sorted(ips), key=get_subnet): groups[k] = list(g) # Sort the groups by most common first for row, (subnet, ips) in enumerate( sorted(groups.iteritems(), key=lambda (k, v): len(v), reverse=True) ): if row > 0: # not the most common subnet print('You probably entered these incorrectly: {}'.format(ips)) 。请注意kwargs中该块头部的注释。使用更简单的参数,它只需设置vectorize.__call__

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

func = self.pyfunc

哪个

self._vectorize_call(func=func, args=vargs)
在大多数情况下,{p> outputs = ufunc(*inputs) < return dtype conversion > ufunc

因此剥夺了所有这些Python封面,它归结为

frompyfunc(func, len(args), nout)

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

总而言之,只要cython是一个难以理解的(或一般的)python函数,your_func就无法改进这一点。迭代已经在编译代码中处理。