我有一个大的 numpy 数组 k
,形状未指定,我想构造一个相同形状的数组 d
当 中的相应条目时为 1.0 k
介于两个常量 lo
和 hi
之间,否则为 0.0。 (由于更大的代码在做什么,我不想要一个 bool 值数组。)
最明显的方法是
d = np.ones_like(k)
d[np.less(k, lo)] = 0
d[np.greater(k, hi)] = 0
但是,np.less
和 np.greater
调用涉及创建大型临时 bool 数组,我认为这是一个很大的开销。有没有一种方法可以在不涉及创建任何大型临时对象的情况下执行此操作,同时保持完全矢量化?
正如其他人所说,numpy 对临时缓冲区的负担很重,而且它没有提供太多控制权。如果内存占用真的是一个障碍,你可以放弃你自己的小例程。例如,
def process(x, lo, hi):
""" lo <= x < hi ? 1.0 : 0.0."""
x_shape = x.shape
xx = np.ascontiguousarray(x).ravel()
out = np.empty_like(xx)
_process(xx, lo, hi, out)
return out.reshape(x_shape)
_process
在 cython 中的位置:
%%cython --annotate
import cython
@cython.boundscheck(False)
@cython.wraparound(False)
def _process(double[::1] x, double lo, double hi, double[::1] out):
""" lo <= x < hi ? 1.0 : 0.0."""
cdef:
Py_ssize_t j
double xj
for j in range(x.shape[0]):
xj = x[j]
if lo <= xj < hi:
out[j] = 1.0
else:
out[j] = 0.0
这里我使用了 jupyter notebook(因此使用了有趣的 %%cython
语法)。在实际项目中,您需要放入 setup.py
来编译扩展等。这样做的好处是否值得,这取决于您。
我是一名优秀的程序员,十分优秀!