Ответ 1
Когда вы используете imgarray = imgarray.astype('B')
, вы получаете копию массива, переданную указанному типу. Для этого требуется дополнительное выделение памяти, даже если вы сразу же переверните imgarray, чтобы указать на вновь выделенный массив.
Если вы используете imgarray.view('uint8')
, вы получите представление о массиве. Это использует те же данные, за исключением того, что оно интерпретируется как uint8
вместо imgarray.dtype
.
(np.dot
возвращает массив uint32
, поэтому после np.dot
, imgarray
имеет тип uint32
.)
Однако проблема с использованием view
заключается в том, что 32-разрядное целое число рассматривается как 4 8-битные целые числа, и мы заботимся только о значении в последних 8 бит. Поэтому нам нужно пропустить каждое четвертое 8-битное целое число. Мы можем сделать это с нарезкой:
imgarray.view('uint8')[:,::4]
Команда IPython% timeit показывает, что происходит значительно ускоренное выполнение таких действий:
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