在分配numpy的用Cython数据视图 [英] Assigning numpy data in cython to a view
问题描述
我想linalg反函数(la.inv)的输出分配给在用Cython视图。不幸的是这是行不通的。我总能la.inv()的输出分配给一个临时ndarray对象,然后将其内容复制到视图。
有没有更好的方式来做到这一点。
cpdef INT testfunc1(np.ndarray [np.float_t,NDIM = 2] A,
双[:,:] b)除-1: 打印(A逆,la.inv(A))
如果np.isnan(A).ANY():
返回-1
其他:
B = la.inv(A)
返回1
cpdef INT testfunc2(np.ndarray [np.float_t,NDIM = 2] A)除-1:
CDEF长P = np.shape(A)[0],状态
CDEF B = np.zeros(形状=(P,P),DTYPE =浮动)
CDEF双[:,:] BView = B
打印(前逆B:B)
状态= testfunc1(A,BView)
打印(后反B:B)
如果状态== -1:
返回-1
其他:
返回1
输出:
A = np.random.ranf(4).reshape(2,2)
状态= testfunc2(A)
如果状态== -1:
提高ValueError错误(南小区。)
其他:
打印(通行证)(前逆B:',阵列([0,0],
[0,0。]]))
('A的倒数:,阵列([4.4407987,-0.10307341]
[-2.26088593,1.19604499]]))
(逆后B:,阵列([0,0],
[0,0。]]))
您可以创建将收到价值的临时缓冲区的 la.inv()
,然后填充内存视图:
导入numpy的是NP
cimport numpy的是NP
进口numpy.linalg如Lacpdef INT testfunc1(np.ndarray [np.float_t,NDIM = 2] A,
双[:,:] b)除-1:
CDEF np.ndarray [np.float_t,NDIM = 2]的buff
CDEF INT I,J 打印(A逆,la.inv(A))
如果np.isnan(A).ANY():
返回-1
其他:
BUFF = la.inv(A)
因为我在范围内(buff.shape [0]):
对于在范围Ĵ(buff.shape [1]):
B〔I,J] = BUFF [I,J]
返回1cpdef INT testfunc2(np.ndarray [np.float_t,NDIM = 2] A)除-1:
CDEF长P = np.shape(A)[0],状态
CDEF B = np.zeros(形状=(P,P),DTYPE =浮动)
CDEF双[:,:] BView = B
打印(前逆B:B)
状态= testfunc1(A,BView)
打印(后反B:B)
如果状态== -1:
返回-1
其他:
返回1
正如@MrE指出的那样,你可以使用 np.copyto()
如果你使用了 np.ndarray
而不是一个MemoryView:
cpdef INT testfunc1(np.ndarray [np.float_t,NDIM = 2] A,
np.ndarray [np.float_t,NDIM = 2] b)除-1:
CDEF INT I,J
打印(A逆,la.inv(A))
如果np.isnan(A).ANY():
返回-1
其他:
np.copyto(B,la.inv(A))
返回1cpdef INT testfunc2(np.ndarray [np.float_t,NDIM = 2] A)除-1:
CDEF长P = np.shape(A)[0],状态
CDEF np.ndarray [np.float_t,NDIM = 2] B,BView
B = np.zeros(形状=(P,P),DTYPE =浮动)
BView = B
打印(前逆B:B)
状态= testfunc1(A,BView)
打印(后反B:B)
如果状态== -1:
返回-1
其他:
返回1
I am trying to assign the output of linalg inverse function (la.inv) to a view in cython. Unfortunately this does not work. I can always assign the output of la.inv() to a temporary ndarray object and then copy its content to the view.
Is there a better way to do it.
cpdef int testfunc1(np.ndarray[np.float_t, ndim=2] A,
double [:,:] B) except -1:
print("inverse of A:", la.inv(A))
if np.isnan(A).any():
return -1
else:
B = la.inv(A)
return 1
cpdef int testfunc2(np.ndarray[np.float_t, ndim=2] A) except -1:
cdef long p = np.shape(A)[0], status
cdef B = np.zeros(shape=(p, p), dtype=float)
cdef double[:,:] BView = B
print("before inverse. B: ", B)
status = testfunc1(A, BView)
print("after inverse. B: ", B)
if status == -1:
return -1
else:
return 1
The output:
A = np.random.ranf(4).reshape(2, 2)
status = testfunc2(A)
if status == -1:
raise ValueError("nan cell.")
else:
print("pass")
('before inverse. B: ', array([[ 0., 0.],
[ 0., 0.]]))
('inverse of A:', array([[ 4.4407987 , -0.10307341],
[-2.26088593, 1.19604499]]))
('after inverse. B: ', array([[ 0., 0.],
[ 0., 0.]]))
You can create a temporary buffer that will receive the value of the la.inv()
and then populate the memory view:
import numpy as np
cimport numpy as np
import numpy.linalg as la
cpdef int testfunc1(np.ndarray[np.float_t, ndim=2] A,
double [:,:] B) except -1:
cdef np.ndarray[np.float_t, ndim=2] buff
cdef int i, j
print("inverse of A:", la.inv(A))
if np.isnan(A).any():
return -1
else:
buff = la.inv(A)
for i in range(buff.shape[0]):
for j in range(buff.shape[1]):
B[i, j] = buff[i, j]
return 1
cpdef int testfunc2(np.ndarray[np.float_t, ndim=2] A) except -1:
cdef long p = np.shape(A)[0], status
cdef B = np.zeros(shape=(p, p), dtype=float)
cdef double[:,:] BView = B
print("before inverse. B: ", B)
status = testfunc1(A, BView)
print("after inverse. B: ", B)
if status == -1:
return -1
else:
return 1
As pointed out by @MrE, you can use np.copyto()
if you use a np.ndarray
instead of a MemoryView:
cpdef int testfunc1(np.ndarray[np.float_t, ndim=2] A,
np.ndarray[np.float_t, ndim=2] B) except -1:
cdef int i, j
print("inverse of A:", la.inv(A))
if np.isnan(A).any():
return -1
else:
np.copyto(B, la.inv(A))
return 1
cpdef int testfunc2(np.ndarray[np.float_t, ndim=2] A) except -1:
cdef long p = np.shape(A)[0], status
cdef np.ndarray[np.float_t, ndim=2] B, BView
B = np.zeros(shape=(p, p), dtype=float)
BView = B
print("before inverse. B: ", B)
status = testfunc1(A, BView)
print("after inverse. B: ", B)
if status == -1:
return -1
else:
return 1
这篇关于在分配numpy的用Cython数据视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!