быстрый способ преобразования массива 16-битного беззнакового интергера в биты - PullRequest
2 голосов
/ 12 февраля 2020

У меня большой набор данных, содержащий трехмерный массив 16-разрядного целого числа без знака. Я хочу преобразовать каждое целое число в биты, а затем сохранить только те, чьи 8:12 битов равны «0000». Пока я использую очень медленный метод l oop в три этапа:

import numpy as np
# Generate random data
a = np.ones([4,1200,1200], dtype="int16")
# Generate an array which serves later as mask
b = np.zeros(a.shape, dtype=int)
for i in range(4):
    for j in range(1200):
        for k in range(1200):
            b[i,j,k] = int('{:016b}'.format(a[i,j,k])[8:12])
a = np.ma.masked_where(b!=0, a)

Я был бы благодарен, если бы вы могли предложить мне чистую и быструю альтернативу для этого

1 Ответ

2 голосов
/ 13 февраля 2020

Ваш вопрос и пример немного сбивают с толку, но обычно, если вы хотите сосредоточиться на определенных битах, вы можете применить двоичный оператор и & с правильной маской. Итак, если вы хотите выбрать «8:12 бит» в 16-битном целом числе без знака, эта маска будет 0b0000000011110000, что составляет 240.

Например, с arr = np.random.randint(0, 2 ** 16 - 1, (6, 6)), я имею получил

array([[28111, 29985,  2056, 24534,  2837, 49004],
       [ 7584,  8798, 38715, 40600, 26665, 51545],
       [34279,  8134, 16112, 59336, 15373, 46839],
       [  131, 12500, 11779, 44852, 57627, 50253],
       [63222, 60588,  9191,  3033, 18643,  8975],
       [17299, 62925, 31776, 10933, 59953, 28443]])

, а затем np.ma.masked_where(arr & 240, arr) дает

masked_array(
  data=[[--, --, 2056, --, --, --],
        [--, --, --, --, --, --],
        [--, --, --, --, 15373, --],
        [--, --, 11779, --, --, --],
        [--, --, --, --, --, 8975],
        [--, --, --, --, --, --]],
  mask=[[ True,  True, False,  True,  True,  True],
        [ True,  True,  True,  True,  True,  True],
        [ True,  True,  True,  True, False,  True],
        [ True,  True, False,  True,  True,  True],
        [ True,  True,  True,  True,  True, False],
        [ True,  True,  True,  True,  True,  True]],
  fill_value=999999)

, что соответствует тому, что вы получите, используя for l oop.

...