Tracing a.compress
通过几层函数调用numpy
github
我到了
/numpy/core/src/multiarray/item_selection.c
PyArray_Compress(PyArrayObject *self, PyObject *condition, int axis,
PyArrayObject *out)
# various checks
res = PyArray_Nonzero(cond);
ret = PyArray_TakeFrom(self, PyTuple_GET_ITEM(res, 0), axis,
out, NPY_RAISE);
使用您的样本阵列,compress
和做一样where
得到一个索引数组,然后take
:
In [135]: a.shape
Out[135]: (1000000, 4)
In [136]: b.shape
Out[136]: (1000000,)
In [137]: a.compress(b, axis=0).shape
Out[137]: (499780, 4)
In [138]: a.take(np.nonzero(b)[0], axis=0).shape
Out[138]: (499780, 4)
In [139]: timeit a.compress(b, axis=0).shape
100 loops, best of 3: 14.3 ms per loop
In [140]: timeit a.take(np.nonzero(b)[0], axis=0).shape
100 loops, best of 3: 14.3 ms per loop
事实上,如果我在 [] 索引中使用这个索引数组,我会得到可比较的时间:
In [141]: idx=np.where(b)[0]
In [142]: idx.shape
Out[142]: (499780,)
In [143]: timeit a[idx,:].shape
100 loops, best of 3: 14.6 ms per loop
In [144]: timeit np.take(a,idx, axis=0).shape
100 loops, best of 3: 9.9 ms per loop
np.take
代码涉及更多,因为它包括clip
and wrap
modes.
[] 索引被翻译成__getitem__
调用,并通过各个层。我还没有发现代码差异很大,但我认为可以肯定地说compress
(更确切地说take
)只是采取更直接的路线来完成任务,从而获得适度的速度提升。 30-50% 的速度差异表明编译代码细节存在差异,而不是诸如此类的重大差异views
vs copies
,或解释与编译。