如何将双指针 ctype 转换为 numpy 数组? [英] How can i cast a double pointer ctype to numpy array?

查看:44
本文介绍了如何将双指针 ctype 转换为 numpy 数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,我得到了这段代码,我用它来将 numpy 2d 数组转换为 ctype 双指针.

import ctypes as ct将 numpy 导入为 nparr = np.empty([500, 500], dtype=np.uint8)UI8Ptr = ct.POINTER(ct.c_uint8)UI8PtrPtr = ct.POINTER(UI8Ptr)ct_arr = np.ctypeslib.as_ctypes(arr)UI8PtrArr = UI8Ptr * ct_arr._length_ct_ptr = ct.cast(UI8PtrArr(*(ct.cast(row, UI8Ptr) for row in ct_arr)), UI8PtrPtr)

如何将 ct_ptr 转换回 numpy 二维数组?

解决方案

注意:这是对 [SO]:如何将二维数组从 Python 传递到 C?.

一种方法是经历以下状态:

  1. CTypes 指针
  2. Python 列表
  3. NumPy 数组

自动出现 2 个观察结果:

  • 效率非常低,但不幸的是我不知道如何摆脱#2.(这是罪魁祸首)
  • 指针包含有关基本类型的信息,但不包含创建它的数组的维度信息,因此您必须保存"它们,因为在解构"指针时需要它们

code00.py:

#!/usr/bin/env python3导入系统将 ctypes 导入为 ct将 numpy 导入为 np定义主():昏暗0 = 3昏暗1 = 4arr0 = np.empty([dim0, dim1], dtype=np.uint8)print("初始数组:\n{0:}".format(arr0))UI8Ptr = ct.POINTER(ct.c_uint8)UI8PtrPtr = ct.POINTER(UI8Ptr)ct_arr = np.ctypeslib.as_ctypes(arr0)UI8PtrArr = UI8Ptr * ct_arr._length_ct_ptr = ct.cast(UI8PtrArr(*(ct.cast(row, UI8Ptr) for row in ct_arr)), UI8PtrPtr)arr1 = np.array([[ct_ptr[i][j] for j in range(dim1)] for i in range(dim0)], dtype=ct_ptr._type_._type_._type_)print("\n最终数组:\n{0:}".format(arr1))打印(\n相等的数组:{0:}".格式(np.array_equal(arr0,arr1)))如果 __name__ == "__main__":print("Python {0:s} {1:d} 位 {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 如果 sys.maxsize > 0x100000000 否则 32, sys.platform))主要的()打印(\n完成.")

输出:

<块引用>

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q058781199]>"e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.pyPython 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 位 (AMD64)] 64 位在 win32初始数组:[[ 96 100 101 115][105 114 101 100][ 96 96 32 115]]最终数组:[[ 96 100 101 115][105 114 101 100][ 96 96 32 115]]相等数组:真完毕.

有关此主题的更多信息请查看 [SO]:将 ctypes 类型数组转换为 void 指针时出现 Numpy 错误(@CristiFati 的回答).

Hey I got this code which i'm using to cast numpy 2d array to ctype double pointer.

import ctypes as ct
import numpy as np

arr = np.empty([500, 500], dtype=np.uint8)

UI8Ptr = ct.POINTER(ct.c_uint8)
UI8PtrPtr = ct.POINTER(UI8Ptr)

ct_arr = np.ctypeslib.as_ctypes(arr)
UI8PtrArr = UI8Ptr * ct_arr._length_
ct_ptr = ct.cast(UI8PtrArr(*(ct.cast(row, UI8Ptr) for row in ct_arr)), UI8PtrPtr)

How can i cast ct_ptr back to numpy 2d array?

解决方案

Note: This is a follow up to [SO]: How to pass a 2d array from Python to C?.

One way would be going through the following states:

  1. CTypes pointer
  2. Python lists
  3. NumPy array

2 observations automatically arise:

  • It's very inefficient, but unfortunately I'm not aware how to get rid of #2. (which is the culprit)
  • The pointer holds information about the base type, but not about the dimension(s) of the array it was created from, so you have to "save" them, as you'll need them when "deconstructing" the pointer

code00.py:

#!/usr/bin/env python3

import sys
import ctypes as ct
import numpy as np


def main():
    dim0 = 3
    dim1 = 4
    arr0 = np.empty([dim0, dim1], dtype=np.uint8)
    print("Initial array:\n{0:}".format(arr0))

    UI8Ptr = ct.POINTER(ct.c_uint8)
    UI8PtrPtr = ct.POINTER(UI8Ptr)

    ct_arr = np.ctypeslib.as_ctypes(arr0)
    UI8PtrArr = UI8Ptr * ct_arr._length_
    ct_ptr = ct.cast(UI8PtrArr(*(ct.cast(row, UI8Ptr) for row in ct_arr)), UI8PtrPtr)

    arr1 = np.array([[ct_ptr[i][j] for j in range(dim1)] for i in range(dim0)], dtype=ct_ptr._type_._type_._type_)
    print("\nFinal array:\n{0:}".format(arr1))
    print("\nEqual arrays: {0:}".format(np.array_equal(arr0, arr1)))


if __name__ == "__main__":
    print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    main()
    print("\nDone.")

Output:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q058781199]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32

Initial array:
[[ 96 100 101 115]
 [105 114 101 100]
 [ 96  96  32 115]]

Final array:
[[ 96 100 101 115]
 [105 114 101 100]
 [ 96  96  32 115]]

Equal arrays: True

Done.

Fore more info on this topic check [SO]: Numpy error when converting array of ctypes types to void pointer (@CristiFati's answer).

这篇关于如何将双指针 ctype 转换为 numpy 数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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