作为标题的补充,我希望有效地对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.html和http://pandas.pydata.org/pandas-docs/stable/enhancingperf.html),这些指南非常有用,但我对C的了解太过狭窄,无法将它们用于潜在的一小部分。
你会怎么做? [Python 3.5.1,Cython 0.25a,Numpy 1.10.4]答案 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)
是一个已编译的函数。我怀疑该函数使用frompyfunc
(nditer
版本)来广播参数,并将值作为标量提供给c
。我在最近的另一篇SO中讨论了your_func
与nditer
的使用。
总而言之,只要cython
是一个难以理解的(或一般的)python函数,your_func
就无法改进这一点。迭代已经在编译代码中处理。