如何将ctypes数组转换为numpy数组

2024-04-25 09:11:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下ctypes数组:

data = (ctypes.c_uint * 100)()

我想创建一个numpy数组np_data,其中包含ctypes数组数据中的整数值(ctypes数组显然稍后会填充值)

我已经看到numpy(https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.ctypes.html)中有一个ctypes接口,但据我所知,这只是从numpy数组中获取ctypes,而不是相反。你知道吗

显然,我可以遍历data并逐个填充np_data数组项,但我想知道是否有更有效/更直接的方法来完成此任务。你知道吗


Tags: 数据httpsorgnumpydocsdatadocnp
2条回答

你可以用[SciPy.Docs]: numpy.ctypeslib.as_array(obj, shape=None)。你知道吗

>>> import ctypes
>>> import numpy as np
>>>
>>> CUIntArr10 = ctypes.c_uint * 10
>>>
>>> ui10 = CUIntArr10(*range(10, 0, -1))
>>>
>>> [ui10[i] for i in range(10)]  # The ctypes array
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>>
>>> np_arr = np.ctypeslib.as_array(ui10)
>>> np_arr  # And the np one
array([10,  9,  8,  7,  6,  5,  4,  3,  2,  1], dtype=uint32)

我没有找到具体的代码行(我也没有测试我的假设),但我有一种感觉,内容复制是由一个memcpy调用完成的,这将使它比从Python中“手动”执行操作快得多。你知道吗

可能最快的是使用^{}。它可以用于实现缓冲区协议的每个对象,特别是ctypes数组。你知道吗

np.frombuffer的主要优点是,ctypes数组的内存根本不是复制的,而是共享的:

data = (ctypes.c_uint * 100)()
arr = np.frombuffer(data, dtype=np.uint32)
arr.flags
# ...
# OWNDATA : False
# ...

通过设置

arr.flags.writable = False

可以确保数据不会通过numpy数组arr更改。你知道吗

如果确实需要复制数据,通常的numpy功能可以用于arr。你知道吗


in@CristiFati's answer建议的np.ctypeslib.as_array似乎是创建numpy数组的更好方法:

  • 内存也是共享的-不涉及复制。你知道吗
  • 右边的dtype是自动使用的(这是一件很好的事情:它消除了错误(正如在我原来的文章中,我使用了np.uint(在我的机器上是指64位无符号整数),而不是np.uint32(在某些架构上也可能不正确)。你知道吗

上述实验证明:

arr = np.ctypeslib.as_array(data)
arr.flags
# ...
# OWNDATA : False
# ...
arr.dtype
# dtype('<u4')

相关问题 更多 >