【问题标题】:Using numpy masking in cython在 cython 中使用 numpy 掩码
【发布时间】:2017-07-07 10:08:29
【问题描述】:

我正在尝试将我的一些 Python 代码转换为 Cython,但在尝试将函数定义为 cdef 时遇到了一些问题。

大部分问题归结为掩码无法像在 Python 中那样工作。我想知道这是否是cdef 的限制(如果我将其保留为def,则可以正常工作)或者是否有什么我可以做的。

比如这个方法

cdef func(double[:,:,:,:] arg1):
    mask = arg1 > 0
    ...

已经因编译错误而失败:

Error compiling Cython file:
------------------------------------------------------------ ...
    func (double[:,:,:,:] arg1):
        mask = arg1 > 0
                   ^
------------------------------------------------------------

cythonfile.pyx:43:20: Invalid types for '>' (double[:, :, :, :], long)

【问题讨论】:

  • 你不应该定义cdef func(np.ndarray[np.float_t, ndim=4] arg1)吗? 0 也是 long integer。将其替换为0. 以获得float
  • @NilsWerner:我刚刚尝试并更改了类型,这似乎可以做到。我之前有 double[:,:] 工作的代码,所以从没想过,但是对于那个代码,我没有使用掩码。我想需要告诉 cython 这是一个允许屏蔽的 numpy 数组。谢谢!
  • 我猜double[:, :] 只允许对元素进行单独寻址,但不能像您正在做的那样进行矢量化操作。
  • 是的,我也这么认为。我以前从未在 Cython 中使用过矢量化操作。

标签: python numpy cython


【解决方案1】:

The docs consistently use np.ndarray[...] in function definitions 所以我会将你的函数签名更改为

cdef func(np.ndarray[np.float_t, ndim=4] arg1):

此外,您正在将 float 数组与 long integer 常量进行比较。改成

mask = arg1 > 0.

比较floatfloat

【讨论】:

    【解决方案2】:

    double[:,:,:,:] 表示法指定参数将被“解释”为Typed Memoryview。这些支持很多操作,但不支持矢量化比较

    但是,将内存视图解释为函数内的 NumPy 数组非常容易:

    import numpy as np
    
    cdef func(double[:,:,:,:] arg1):
        arg1arr = np.asarray(arg1)
        mask = arg1arr > 0.
    

    这甚至不需要副本,因此在内存视图上执行np.asarray 基本上是“免费的”。这允许将内存视图的优势与 NumPy 数组上可能的矢量化操作相结合。

    但是,对于不需要 Cython 的向量化操作,您可以在纯 python 函数中执行所有向量化操作,并且只使用 Cython 来完成“普通 NumPy”函数无法实现的繁重工作。

    【讨论】:

    • 传入np.ndarraydouble[...] 参数在性能方面有什么区别吗?您说np.asarray 的创建是“免费的”,但其他操作也是如此吗?
    • @orange 这取决于您的用例。这里已经介绍了几个方面,例如"Cython: are typed memoryviews the modern way to type numpy arrays?" 或在一些博客中"Memoryview Benchmarks"。 memoryviews 的问题是某些矢量化操作不可用。另一方面,向量化操作不需要 Cython(因为它们和 Python 一样快)。
    • @orange 我发现在高速数学库中使用 ndarray 和 [:,:] 格式的相同代码之间没有性能差异
    • @Matt:如果转换为 np.ndarray 是“免费”的,那是有道理的。感谢您的澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 2013-05-19
    • 1970-01-01
    • 2011-11-03
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多