Я нахожу 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 битовых массивов в файл
Когда вы используете 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