在分配numpy的用Cython数据视图 [英] Assigning numpy data in cython to a view

查看:216
本文介绍了在分配numpy的用Cython数据视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆