Преобразование массива структур C в массив numpy

#python #arrays #python-3.x #numpy #ctypes

#python #массивы #python-3.x #numpy #ctypes

Вопрос:

Функция, которую я вызываю из общей библиотеки, возвращает структуру с именем info, похожую на эту:

 typedef struct cmplx {
  double real;
  double imag;
} cmplx;

typedef struct info{
  char *name;
  int arr_len;
  double *real_data
  cmplx *cmplx_data;
} info;
 

Одно из полей структуры представляет собой массив двойных чисел, а другое — массив комплексных чисел. Как мне преобразовать массив комплексных чисел в массив numpy? Для удвоений у меня есть следующее:

 from ctypes import *
import numpy as np

class cmplx(Structure):
    _fields_ = [("real", c_double),
                ("imag", c_double)]


class info(Structure):
    _fields_ = [("name", c_char_p),
                ("arr_len", c_int),
                ("real_data", POINTER(c_double)),
                ("cmplx_data", POINTER(cmplx))]

c_func.restype = info
ret_val = c_func()
data = np.ctypeslib.as_array(ret_val.contents.real_data, shape=(info.contents.arr_len,))
 

Существует ли строка numpy one для комплексных чисел? Я могу сделать это с помощью циклов.

Ответ №1:

Определите ваше поле как double и создайте сложное представление с помощью numpy:

 class info(Structure):
    _fields_ = [("name", c_char_p),
                ("arr_len", c_int),
                ("real_data", POINTER(c_double)),
                ("cmplx_data", POINTER(c_double))]

c_func.restype = info
ret_val = c_func()
data = np.ctypeslib.as_array(ret_val.contents.real_data, shape=(info.contents.arr_len,))
complex_data = np.ctypeslib.as_array(ret_val.contents.cmplx_data, shape=(info.contents.arr_len,2)).view('complex128')
 

Комментарии:

1. Разделяемая библиотека требует, чтобы поле было указателем на структуру cmplx.

2. Хорошо, это сработало. Не могли бы вы объяснить, почему? C требует, чтобы это был указатель на структуру cmplx, но мы используем указатель на объект c_double в python.

3. комплексное число — это не что иное, как два удвоения. Для интерфейса тип не важен (вы даже можете использовать байты). В конце концов, представление вашего numpy-массива определяет тип.

4. Я понимаю. Большое вам спасибо за вашу помощь!