如何从指针创建一个n维numpy数组?

11

我了解numpy.frombuffer,但找不到从指针创建数组的方法。


这个问题在这里已经得到解答:https://dev59.com/aWoy5IYBdhLWcg3wMLSj - ebarr
1个回答

21

正如上面的评论所指出的那样,您可以使用 numpy.ctypeslib.as_array

numpy.ctypeslib.as_array(obj, shape=None)

从ctypes数组或ctypes POINTER创建一个numpy数组。numpy数组与ctypes对象共享内存。

如果从ctypes POINTER转换,则必须给出size参数。如果从ctypes数组转换,则忽略size参数。

因此,让我们通过调用 malloc 来模拟返回指针的 C 函数:

import ctypes as C
from ctypes.util import find_library
import numpy as np

SIZE = 10

libc = C.CDLL(find_library('c'))
libc.malloc.restype = C.c_void_p

# get a pointer to a block of data from malloc
data_pointer = libc.malloc(SIZE * C.sizeof(C.c_int))
data_pointer = C.cast(data_pointer,C.POINTER(C.c_int))

现在,您可以使此指针所指向的数据可用于numpy

new_array = np.ctypeslib.as_array(data_pointer,shape=(SIZE,))

为了证明它们正在访问同一块内存:

new_array[:] = range(SIZE)

print "Numpy array:",new_array[:SIZE]
print "Data pointer: ",data_pointer[:SIZE]
应输出:

should output:

Numpy array: [0 1 2 3 4 5 6 7 8 9]
Data pointer:  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

最后需要记住的一点是,NumPy数组并不拥有其内存,因此需要显式调用free来避免内存泄漏。

del new_array
libc.free(data_pointer)

1
该库可能正在使用自定义分配器,或者特别是在Windows上,它可能与不同的CRT链接。通常,该库应导出一个函数来“释放”它分配的内存。 - Eryk Sun
每次对新指针调用 as_array 都必须在指针上创建和存储一个 __array_interface__。我记得有一个问题抱怨这样做的性能。使用数组类型或由 ndpointer 创建的 c_void_p 子类不会产生这种成本,但它不够灵活。 - Eryk Sun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接