python - 将 cython 中的 numpy 数据分配给 View

标签 python arrays numpy cython memoryview

我正在尝试将 linalg 反函数 (la.inv) 的输出分配给 cython 中的 View 。不幸的是这不起作用。我总是可以将 la.inv() 的输出分配给临时 ndarray 对象,然后将其内容复制到 View 。

有没有更好的方法来做到这一点。

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

输出:

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.]]))

最佳答案

您可以创建一个临时缓冲区,该缓冲区将接收 la.inv() 的值,然后填充内存 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

正如@MrE所指出的,如果您使用np.ndarray而不是MemoryView,则可以使用np.copyto():

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

关于python - 将 cython 中的 numpy 数据分配给 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23827902/

相关文章:

bash - 在不指定 Bash 中的索引的情况下向数组添加新元素

php - mysql 在序列化数组中选择查询

python - Pandas — 将数据集行从每个个体更改为每个操作的最简单方法

python - 检查两个numpy数组python中有多少元素相等

python - 修改 django 管理用户界面

python - URLlib 未显示在谷歌分析中

python - OSError : [Errno 22] Invalid argument on file path while modifying a file

python 正则表达式从文本中省略复杂的引用样式

javascript - 基于对象数组中不同单位的总和值

python - 在频谱 numpy 中找到峰值位置