【问题标题】:Declaring a numpy boolean mask in Cython在 Cython 中声明一个 numpy 布尔掩码
【发布时间】:2018-01-04 04:55:46
【问题描述】:

我应该如何在 Cython 中声明布尔掩码的类型?我真的需要申报吗?示例如下:

cpdef my_func(np.ndarray[np.double_t, ndim = 2] array_a,
            np.ndarray[np.double_t, ndim = 2] array_b,
            np.ndarray[np.double_t, ndim = 2] array_c):

    mask = ((array_a > 1) & (array_b == 2) & (array_c == 3)
    array_a[mask] = 0.
    array_b[mask] = array_c[mask]
    return array_a, array_b, array_c

【问题讨论】:

  • 为了完整起见,您的问题可能需要更多信息:实际的错误消息以及您构建array_a&Co 的方式
  • 我的猜测:应该是np.bool 而不是np.uint8_t,即cdef np.ndarray[np.bool, ndim = 2] mask...
  • @ead 在使用cdef np.ndarray[np.bool, ndim = 2] 时会出现无效类型错误
  • 我可以在代码中的任何地方声明类型还是必须在 def 之后的第一行?

标签: python numpy cython cythonize


【解决方案1】:

您需要通过np.ndarray[np.uint8_t, ndim = 2, cast=True] mask = ...np.uint8_t“转换”为bool,即

cimport numpy as np
cpdef my_func(np.ndarray[np.double_t, ndim = 2] array_a,
            np.ndarray[np.double_t, ndim = 2] array_b,
            np.ndarray[np.double_t, ndim = 2] array_c):
    cdef np.ndarray[np.uint8_t, ndim = 2, cast=True] mask = (array_a > 1) & (arr
ay_b == 2) & (array_c == 3)
    array_a[mask] = 0.
    array_b[mask] = array_c[mask]
    return array_a, array_b, array_c

否则(没有cast=True)代码会编译,但由于类型不匹配而在运行时抛出。

但是,您根本不需要定义 mask 的类型,并且可以将其用作 python 对象:会有一些性能损失,或者更准确地说,错过了加快速度的机会通过早期类型绑定,但在你的情况下它可能并不重要。


还有一件事:我不知道您的真实代码是什么样的,但我希望您知道,cython 根本不会加速您的示例 - 与 numpy 相比没有什么好处。


我们可以轻松验证 bool-np.array 每个值使用 8 位(至少在我的系统上)。这一点都不明显,例如每个值只能使用一点(很像bitset):

import sys
import numpy as np
a=np.random.random((10000,))
sys.getsizeof(a)
>>> 80096
sys.getsizeof(a<.5)
>>> 10096

很明显,双精度数组每个元素需要 8 个字节 + 86 字节开销,掩码每个元素只需要一个字节。

我们还可以看到,False0 表示,True1 表示:

print (a<.5).view(np.uint8)
[1 0 1 ..., 0 0 1]

使用cast=True 可以访问底层数组中的原始字节,这是对数组内存的一种重新解释。

Here 是一些信息,虽然很旧。

【讨论】:

  • 为什么 Cython 不能加速这段代码?是因为以优化的方式使用 numpy 吗?
  • @BehzadJamali 这个函数没有“工作”——它只调用 numpy 功能——没有什么可以加速的。 Numpy 主要是预编译的 C 代码,因此您不太可能通过在 cython 中重写功能来加速它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
相关资源
最近更新 更多