Numpy Cython Memoryview中的阵列广播
我用cython创建了一个类型化的memoryview,并希望将其乘以标量:Numpy Cython Memoryview中的阵列广播,numpy,cython,array-broadcasting,typed-memory-views,Numpy,Cython,Array Broadcasting,Typed Memory Views,我用cython创建了一个类型化的memoryview,并希望将其乘以标量: 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)
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
函数foo()
执行此任务,但不太方便/可读
但是,函数bar()
中的行A*=pi
未编译:对“*”的操作数类型无效(double_t[:,:];double)
有没有办法在cython memoryview上执行这样的广播操作?没有,memoryview不会这样做。memoryview实际上只是一种快速访问数组中单个元素的方法。它没有可以在数组上执行的数学运算的真正概念 对于
bar
函数,任何尝试键入它的操作都可能会使情况变得更糟(即,它将花费额外的时间检查类型,但最终工作是在对Numpy函数的普通调用中完成的)
从memoryview中获取Numpy数组有多种方法(并非100%令人满意):
np.asarray(memview)
-这应该在不复制的情况下完成(前提是您没有使用深奥的间接内存布局)。也许值得添加一个断言来检查是否没有复制
memview.base
-对此要稍微小心。如果memoryview是切片的结果,则.base
将是原始的未切片对象
Anp = np.array(...)
cdef double[:] Amview = Anp
因为memoryview是一些内存的视图,所以对数组的修改将反映在memoryview中,反之亦然。(但不会反映重新分配数组变量,例如,Anp=something\u other
)
总之,MemoryView是为一项主要工作而设计的:能够快速访问单个元素。如果这不是您正在做的,那么您可能不想使用memoryview。谢谢您的建议!您是对的,最好的方法可能是使用类型化的memviews进行快速索引,或者使用经典的numpy函数。