numpy: Как преобразовать тип массива быстро

Я нахожу astype (), метод numpy выстраивает не очень эффективный. У меня есть массив, содержащий 3 миллиона из точки Uint8. При умножении его на 3x3 матрица берет 2-секундный, но преобразование результата uint16 к uint8 занимает другую секунду.

Более точно:

    print time.clock()
    imgarray = np.dot(imgarray,  M)/255
    print time.clock()
    imgarray = imgarray.clip(0, 255)
    print time.clock()
    imgarray = imgarray.astype('B')
    print time.clock()

скалярное произведение и масштабирование занимают 2 секунды
отсечение берет 200 преобразований типов мс, занимает 1 секунду

Учитывая время, потраченное другими операциями, я ожидал бы astype быть быстрее. Существует ли более быстрый способ сделать преобразование типов или я неправильно при приблизительной оценке, то преобразование типов не должно быть этим трудно?

Редактирование: цель состоит в том, чтобы сохранить заключительные 8 битовых массивов в файл

15
задан shodanex 11 December 2009 в 17:41
поделиться

1 ответ

Когда вы используете imgarray = imgarray.astype ('B') , вы получаете копию массива, приведенную к указанному типу. Это требует дополнительного выделения памяти, даже если вы сразу перевернете imgarray, чтобы указать на вновь выделенный массив.

Если вы используете imgarray.view ('uint8') , то вы получите представление о массиве. При этом используются те же данные, за исключением того, что они интерпретируются как uint8 вместо imgarray.dtype . ( np.dot возвращает массив uint32 , поэтому после np.dot , imgarray имеет тип uint32 ].)

Проблема с использованием представления , однако, заключается в том, что 32-битное целое число рассматривается как 4 8-битных целых числа, и нас заботит только значение в последних 8 битах. Поэтому нам нужно переходить к каждому четвертому 8-битному целому числу. Мы можем сделать это с помощью нарезки:

imgarray.view ('uint8') [:, :: 4]

Команда% timeit IPython показывает, что это значительно ускорило выполнение таких действий:

In [37]: %timeit imgarray2 = imgarray.astype('B')
10000 loops, best of 3: 107 us per loop

In [39]: %timeit imgarray3 = imgarray.view('B')[:,::4]
100000 loops, best of 3: 3.64 us per loop
25
ответ дан 1 December 2019 в 02:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: