Передача ** массива с плавающей запятой из C ++ Dll в python - PullRequest
0 голосов
/ 19 июня 2020

В настоящее время я работаю с функциями C / C ++, импортированными в python благодаря Dll и ctypes. В DLL у меня есть функция, которая принимает в качестве аргумента переменную типа float **. Этот аргумент заполняется функцией, и я возвращаю его на python с помощью ctypes.

У меня есть решение, которое работает с использованием 2 циклов for, но это очень медленно, когда в 2D-массиве много точек.

Вы знаете, как обойтись без этих циклов for?

Вот мой код:

Краткая версия экспортируемой функции (DLL)

unsigned short ClassExample::GetData(float **Samples)
{
    for(long i = 0; i < rows; i++)
    {
        try
        {
            if(ch < NB_ROWS_MAX) 
            {
                Samples[ch]][i] = this->Data[ch][i];
            }
            else
            {
                ...
            }
        } ...

Python код

def GetSamples(self, ROWS, COLUMN):

    Data = (ctypes.POINTER(ctypes.c_float) * ROWS)()
    for i in range(COLUMN):
        Data[i] = (ctypes.c_float * COLUMN)()

    try:
        succeed = lib._PyGetData(ClassExampleObj, ctypes.byref(Data))
        if succeed != 0:
            print("Error number :", succeed)
    except:
        print("Unknown Error")

    Data_np = numpy.zeros((ROWS, COLUMN), dtype=float)
    for i in range(ROWS):
        for j in range(COLUMN):
            Data_np[i, j] = float(Data[i][j])
    return Data_np

Спасибо!

1 Ответ

0 голосов
/ 19 июня 2020

Если ваша проблема заключается в эффективности, то вы, вероятно, работаете с очень большими наборами данных.

Самый простой способ сделать итерацию двумерной матрицы намного быстрее - сделать ее одномерной. Если у вас есть X столбцов и Y строк, то вместо доступа к matrix[I][j] вы можете получить доступ к matrix[i*X+j], что избавит вас от разыменования и, возможно, многих промахов кеша. Если возможно, вы можете даже go дальше и обрабатывать матрицу как одномерный массив.

Еще одно решение, позволяющее сэкономить время, - как можно больше избегать условий. Если у вас есть только условия внутри for-l oop, компилятор сможет их значительно оптимизировать.

Не видя больше вашего кода, трудно сказать, есть ли у вас неэффективный код или просто обрабатываете слишком много данных для вашего компьютера, но рекомендации, которые я дал, похоже, соответствуют приведенному вами примеру.

Последнее, что я хочу упомянуть, это то, что float довольно неточно, и вам лучше использовать double, если возможно.

Удачи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...