Binary numpy array to list of integers?
I once asked a similar question here. Here was my answer, adapted for your question:
def bool2int(x):
y = 0
for i,j in enumerate(x):
y += j<<i
return y
In [20]: a
Out[20]:
array([[1, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 1],
[1, 1, 1, 1]])
In [21]: [bool2int(x[::-1]) for x in a]
Out[21]: [12, 4, 7, 15]
How to change a binary numpy array into an int?
At first, convert Numpy array to string by simply appending elements.
Then, using int(), recast the string using base of 2.
koo = np.random.randint(2, size=10)
print(koo)
binaryString = ""
for digit in koo:
binaryString += str(digit)
print(binaryString)
decimalString = int(binaryString, base=2)
print(decimalString)
An example run:[0 0 1 0 1 0 0 0 0 0]
0010100000
160
Convert binary (0|1) numpy to integer or binary-string?
One way would be using dot-product
with 2-powered
range array -
b.dot(2**np.arange(b.size)[::-1])
Sample run -In [95]: b = np.array([1,0,1,0,0,0,0,0,1,0,1])
In [96]: b.dot(2**np.arange(b.size)[::-1])
Out[96]: 1285
Alternatively, we could use bitwise left-shift operator to create the range array and thus get the desired output, like so -b.dot(1 << np.arange(b.size)[::-1])
If timings are of interest -In [148]: b = np.random.randint(0,2,(50))
In [149]: %timeit b.dot(2**np.arange(b.size)[::-1])
100000 loops, best of 3: 13.1 µs per loop
In [150]: %timeit b.dot(1 << np.arange(b.size)[::-1])
100000 loops, best of 3: 7.92 µs per loop
Reverse process
To retrieve back the binary array, use np.binary_repr
alongwith np.fromstring
-
In [96]: b = np.array([1,0,1,0,0,0,0,0,1,0,1])
In [97]: num = b.dot(2**np.arange(b.size)[::-1]) # integer
In [98]: np.fromstring(np.binary_repr(num), dtype='S1').astype(int)
Out[98]: array([1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1])
Converting Binary Numpy Array into Unsigned Integer
We could slice out the first 4
columns and last 8
columns and use np.packbits
separately on those. Then, scale the first slice to account for them being the most-significant block among them and add with the second slice.
Hence, the implementation would be -
slice0 = np.packbits(b[:,:-8], axis=-1).astype(np.uint16) * 16
slice1 = np.packbits(b[:,-8:], axis=-1).astype(np.uint16)
out = slice0 + slice1
Alternatively, using sum-redcution
with matrix-multiplication
-b.dot(2**np.arange(b.shape[1]-1,-1,-1))
Sample run -In [1045]: b
Out[1045]:
array([[0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0]], dtype=uint8)
In [1046]: slice0 = np.packbits(b[:,:-8], axis=-1).astype(np.uint16) * 16
...: slice1 = np.packbits(b[:,-8:], axis=-1).astype(np.uint16)
...: out = slice0 + slice1
...:
In [1047]: out.ravel()
Out[1047]: array([1786, 248, 248, 250, 248, 248, 248, 248, 1272, 760])
In [1048]: b.dot(2**np.arange(b.shape[1]-1,-1,-1))
Out[1048]: array([1786, 248, 248, 250, 248, 248, 248, 248, 1272, 760])
Converting a numpy array of zeros and ones into an array of binary numbers
np.packbits
does that. However, the bits of resulting array are stored in block of np.uint8
items. This means that a.shape[1] <= 8
must be true. Moreover, it packs bits on the right (in bigendian mode) so you need to shift the values. Here is the resulting code:
np.packbits(a, bitorder='big', axis=1) >> (8-a.shape[1])
If you need the code to work with a.shape[1] > 8
, then you can write a Numba code based on this previous post. Vectorized conversion of decimal integer array to binary array in numpy
The quickest way I've found (so far) is to use the pd.Series.apply()
function.
Here are the testing results:
import pandas as pd
import numpy as np
x = np.random.randint(1,10000000,1000000)
# Fastest method
%timeit pd.Series(x).apply(bin)
# 135 ms ± 539 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# rafaelc's method
%timeit [np.binary_repr(z) for z in x]
# 725 ms ± 5.31 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# aparpara's method
binary_repr_v = np.vectorize(np.binary_repr)
%timeit binary_repr_v(x, 8)
# 7.46 s ± 24.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Expand 2-D Numpy integer Array as binary but in parallel
Came up with this approach:
def expand_multi_bin(a):
# Create result array
n = np.max(a, axis=0).sum()
d = a.shape[0]
newa = np.zeros(d*n).reshape(d,n)
row=0
for x in np.nditer(a, flags=['external_loop'], order='F'):
# Iterate each column
for idx,c in enumerate(np.nditer(x)):
# Store it to the result array
newa[idx,row:row+c] = np.ones(c)
row += np.max(x)
return newa
Though, given the multiple loops, highly skeptical that this is the best approach. Convert a NumPy array to a binary array with the condition of each element existing in a list
Check out https://numpy.org/doc/stable/reference/generated/numpy.isin.html
arr=np.array([[23,43,1],[43,5,0],[5,0,0]])
l = [5,43]
np.isin(arr, l).astype(int)
#array([[0, 1, 0],
# [1, 1, 0],
# [1, 0, 0]])
convert each element in array to binary python
Numpy has a fast function np.binary_repr()
that does what you want for an individual number. You can apply it to an array with np.vectorize()
:
import numpy as np
l = np.arange(12).reshape([3, 4])
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
np.vectorize(np.binary_repr)(l, 8)
# array([['00000000', '00000001', '00000010', '00000011'],
# ['00000100', '00000101', '00000110', '00000111'],
# ['00001000', '00001001', '00001010', '00001011']], dtype='<U8')
Convert NumPy array to 0 or 1 based on threshold
np.where
np.where(a > 0.5, 1, 0)
# array([0, 0, 0, 1, 1, 1])
Boolean basking with astype
(a > .5).astype(int)
# array([0, 0, 0, 1, 1, 1])
np.select
np.select([a <= .5, a>.5], [np.zeros_like(a), np.ones_like(a)])
# array([ 0., 0., 0., 1., 1., 1.])
Special case: np.round
This is the best solution if your array values are floating values between 0 and 1 and your threshold is 0.5.a.round()
# array([0., 0., 0., 1., 1., 1.])
Related Topics
Understanding the Python with Statement and Context Managers
Detect File Change Without Polling
Handling of Duplicate Indices in Numpy Assignments
Join Two Lists of Dictionaries on a Single Key
Removing Time from Date&Time Variable in Pandas
Create File But If Name Exists Add Number
Fastest Way to Sort Each Row in a Pandas Dataframe
Rename Multiindex Columns in Pandas
Why Isn't .Ico File Defined When Setting Window's Icon
Pandas Read_CSV and Filter Columns with Usecols
In What Order Does Python Display Dictionary Keys
Why Does Numpy.Zeros Takes Up Little Space
"Permission Denied" Trying to Run Python on Windows 10
Determine Prefix from a Set of (Similar) Strings
Matplotlib Custom Marker/Symbol
Bad Idea to Catch All Exceptions in Python
When Should an Attribute Be Private and Made a Read-Only Property