Преобразовать цепочку битов (строка из 1 и 0) в массив NumPy
У меня есть пандас Dataframe, содержащий 1 столбец, который содержит строку битов, например.'100100101'
, Я хочу преобразовать эту строку в массив NumPy.
Как я могу это сделать?
РЕДАКТИРОВАТЬ:
С помощью
features = df.bit.apply(lambda x: np.array(list(map(int,list(x)))))
#...
model.fit(features, lables)
приводит к ошибке на model.fit
:
ValueError: setting an array element with a sequence.
Решение, которое работает для моего случая, я придумал из-за отмеченного ответа:
for bitString in input_table['Bitstring'].values:
bits = np.array(map(int, list(bitString)))
featureList.append(bits)
features = np.array(featureList)
#....
model.fit(features, lables)
2 ответа
Для строки s = "100100101"
Вы можете преобразовать его в массив NumPy по крайней мере двумя разными способами.
Первый с помощью Numpy's fromstring
метод. Это немного неловко, потому что вы должны указать тип данных и вычесть "базовое" значение элементов.
import numpy as np
s = "100100101"
a = np.fromstring(s,'u1') - ord('0')
print a # [1 0 0 1 0 0 1 0 1]
куда 'u1'
это тип данных и ord('0')
используется для вычитания "базового" значения из каждого элемента.
Второй способ заключается в преобразовании каждого строкового элемента в целое число (поскольку строки являются итеративными), а затем передачу этого списка в np.array
:
import numpy as np
s = "100100101"
b = np.array(map(int, s))
print b # [1 0 0 1 0 0 1 0 1]
затем
# To see its a numpy array:
print type(a) # <type 'numpy.ndarray'>
print a[0] # 1
print a[1] # 0
# ...
Обратите внимание, что второй подход масштабируется значительно хуже первого, поскольку длина входной строки s
увеличивается. Для небольших строк это близко, но рассмотрим timeit
результаты для строк из 90 символов (я только что использовал s * 10
):
fromstring: 49.283392424 s
map/array: 2.154540959 s
(Это по умолчанию timeit.repeat
аргументы, минимум 3 запуска, каждый из которых вычисляет время для выполнения 1M строк-> преобразований массивов)
Одним из методов pandas было бы вызвать apply для столбца df для выполнения преобразования:
In [84]:
df = pd.DataFrame({'bit':['100100101']})
t = df.bit.apply(lambda x: np.array(list(map(int,list(x)))))
t[0]
Out[84]:
array([1, 0, 0, 1, 0, 0, 1, 0, 1])
Проверьте unpackbits
>>> np.unpackbits(np.array([int('010101',2)], dtype=np.uint8))
array([0, 0, 0, 1, 0, 1, 0, 1], dtype=uint8)
И в целом:
>>> a = np.array([[2], [7], [23]], dtype=np.uint8)
>>> a
array([[ 2],
[ 7],
[23]], dtype=uint8)
>>> b = np.unpackbits(a, axis=1)
>>> b
array([[0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)
Если вам нужно больше 8 бит, ознакомьтесь с разделом Как извлечь биты больших числовых типов данных Numpy