【问题标题】:How to convert a ctypes array of c_uint to a numpy array如何将 c_uint 的 ctypes 数组转换为 numpy 数组
【发布时间】:2019-08-27 21:58:48
【问题描述】:

我有以下 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 数组项,但我想知道是否有更有效/更直接的方法来完成这项任务。

【问题讨论】:

    标签: python arrays numpy ctypes


    【解决方案1】:

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

    >>> import ctypes as ct
    >>> import numpy as np
    >>>
    >>>
    >>> CUIntArr10 = ctypes.c_uint * 10
    >>>
    >>> ui10 = CUIntArr10(*range(10, 0, -1))
    >>>
    >>> [i for i in ui10]  # 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“手动”做事要快得多。

    【讨论】:

      【解决方案2】:

      可能最快的是使用np.frombuffer。它可以与实现缓冲区协议的每个对象一起使用,特别是与 ctypes-arrays 一起使用。

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

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

      通过设置

      arr.flags.writable = False
      

      可以确保,不会通过 numpy-array arr 更改数据。

      如果确实需要复制数据,则可以将通常的 numpy 功能用于arr


      @CristiFati's answer 中提出的np.ctypeslib.as_array 似乎是创建 numpy-array 的更好方法:

      • 内存也是共享的 - 不涉及复制。
      • 自动使用正确的dtype(这是一件好事:它消除了错误(如在我的原始帖子中,我使用np.uint(在我的机器上表示64位无符号整数)而不是np.uint32 (在某些架构上也可能不正确)。

      以上实验证明:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-18
        • 1970-01-01
        • 1970-01-01
        • 2021-06-09
        • 1970-01-01
        相关资源
        最近更新 更多