Булевский массив с 1-битными записями - PullRequest
28 голосов
/ 09 апреля 2011

Есть ли способ в numpy создать массив логических значений, который использует только 1 бит для каждой записи?

Стандартный тип np.bool равен 1 байту, но таким образом я использую 8 раз необходимую память.

В Google я обнаружил, что в C ++ есть std::vector<bool>.

Ответы [ 3 ]

15 голосов
/ 09 апреля 2011

Вы хотите bitarray :

эффективные массивы логических значений - расширение C

Этот модуль предоставляет тип объекта, который эффективно представляет массив логических значений. Bitarrays являются типами последовательностей и ведут себя очень похоже на обычные списки. Восемь битов представлены одним байтом в непрерывном блоке памяти. Пользователь может выбирать между двумя представлениями; little-endian и big-endian. Все функциональные возможности реализованы в C. Предоставлены методы для доступа к представлению машины. Это может быть полезно, когда требуется доступ на двоичном уровне к двоичным файлам, таким как файлы переносимых растровых изображений (.pbm). Кроме того, при работе со сжатыми данными, использующими кодирование переменной битовой длины, этот модуль может оказаться полезным ...

10 голосов
/ 07 июля 2017

Для этого вы можете использовать нубийские packbits и unpackbits . Первая функция проста в использовании, но для ее реконструкции вам потребуются дополнительные манипуляции. Вот пример:

import numpy as np
# original boolean array
A1 = np.array([
    [0, 1, 1, 0, 1],
    [0, 0, 1, 1, 1],
    [1, 1, 1, 1, 1],
], dtype=np.bool)

# packed data
A2 = np.packbits(A1, axis=None)

# checking the size
print len(A1.tostring()) # 15 bytes
print len(A2.tostring()) #  2 bytes (ceil(15/8))

# reconstructing from packed data. You need to resize and reshape
A3 = np.unpackbits(A2, axis=None)[:A1.size].reshape(A1.shape).astype(np.bool)

# and the arrays are equal
print np.array_equal(A1, A3) # True
10 голосов
/ 09 апреля 2011

Возможно, вы захотите взглянуть на цепочку битов (документация здесь ).

Если вы создаете ConstBitArray или ConstBitStream из файла, он будет использовать mmap и не загружать его в память. В этом случае он не будет изменяемым, поэтому, если вы хотите внести изменения, он должен быть загружен в память.

Например, чтобы создать без загрузки в память:

>>> a = bitstring.ConstBitArray(filename='your_file')

или

>>> b = bitstring.ConstBitStream(a_file_object)
...