簡體   English   中英

Cython Memoryview 中的陣列廣播

[英]Array-Broadcasting in Cython Memoryview

我在 cython 中創建了一個類型化的內存視圖,並想將它乘以一個標量:

import numpy as np
import math
cimport numpy as np

def foo():
    N = 10
    cdef np.double_t [:, :] A = np.ones(shape=(N,N),dtype=np.double_)
    cdef int i,j
    cdef double pi = math.pi
    for i in range(N):
        for j in range(N):
            A[i,j] *= pi
    return A

def bar():
    N = 10
    cdef np.double_t [:, :] A = np.ones(shape=(N,N),dtype=np.double_)
    cdef double pi = math.pi
    A *= pi
    return A

Function foo()執行此任務,但不是很方便/可讀。

但是,function bar()中的A *= pi行無法編譯: Invalid operand types for '*' (double_t[:, :]; double)

有沒有辦法在 cython memoryview 上執行這樣的廣播操作?

不,內存視圖不這樣做。 內存視圖實際上只是一種快速訪問數組中各個元素的方法。 它沒有可以在數組上執行的數學運算的真正概念。

在你的bar function 的情況下,任何嘗試鍵入它實際上可能會使它變得更糟(即它會花費額外的時間檢查類型,但最終工作是在對 Numpy 函數的普通調用中完成的)。

從 memoryview 獲取 Numpy 數組的方法有很多(不是 100% 令人滿意):

  1. np.asarray(memview) - 這應該在不復制的情況下完成(前提是您沒有使用深奧的間接 memory 布局)。 可能值得添加一個斷言來檢查是否沒有復制。

  2. memview.base - 對此要稍微小心。 如果 memoryview 是切片的結果,那么.base將是原始未切片的 object。

  3. 保持一個並行的 numpy 數組和 memoryview 變量:

     Anp = np.array(...) cdef double[:] Amview = Anp

    因為 memoryview 是一些 memory 的視圖,所以對數組的修改會反映在 memoryview 中,反之亦然。 (但不會反映重新分配數組變量,例如Anp = something_else )。


總之,內存視圖是為一項主要工作而設計的:能夠快速訪問單個元素。 如果那不是您正在做的事情,那么您可能不想使用內存視圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM