I'm having a binary MxN matrix like the following:
matrix([[0, 0, 0, ..., 0, 0, 0],
[0, 1, 0, ..., 0, 0, 0],
[0, 0, 1, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 1, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 1]])
How can I convert this matrix row-wise to the integer representation? The goal is to get a Mx1 matrix. Each row contains the integer representation of the previous binary row.
-
1possible duplicate of Binary numpy array to list of integers?Warren Weckesser– Warren Weckesser2015年03月30日 10:59:12 +00:00Commented Mar 30, 2015 at 10:59
3 Answers 3
Another approach is using packbits from numpy. For this, however, numpy will fill with zeros the columns, until they get byte shape (length % 8). In order to avoid numpy from filling with 0's, we could add zeros at the beginning (to not change the binary value of the array).
Using the data from @Oliver W.
>>> import numpy as np
>>> b = np.random.random_integers(0,1,(3,5))
>>> b
array([[0, 1, 1, 1, 0],
[1, 0, 1, 0, 1],
[0, 1, 0, 0, 1]])
# Fill the begining with zeros to form bytes
>>> diff = 8 - b.shape[1] % 8
>>> if diff > 0: b = np.c_[np.zeros((b.shape[0], diff), int), b]
>>> b
array([[0, 0, 0, 0, 1, 1, 1, 0],
[0, 0, 0, 1, 0, 1, 0, 1],
[0, 0, 0, 0, 1, 0, 0, 1]])
# Get the integer number
>>> p = np.packbits(b, axis=1)
>>> p
array([[14],
[21],
[ 9]], dtype=uint8)
2 Comments
Mx1.p.view('u4') (for a 32 bit integer, similar for others). It would return a new view for the columnsYou could multiply each element of the row with its corresponding multiplication factor 2**exponent where the exponent depends on the position of the digit within the row (this works for any positional number system by the way, such as base-60 and hexadecimal):
>>> import numpy as np
>>>
>>> b = np.random.random_integers(0,1,(3,5)) # example array
>>> b
array([[0, 1, 1, 1, 0],
[1, 0, 1, 0, 1],
[0, 1, 0, 0, 1]])
>>> c = 2**np.arange(b.shape[1])[::-1] # reverse order: assumes the last column corresponds with the decimal number 1
>>> b.dot(c) # matrix multiplication
array([14, 21, 9])
Same result if you have instances of numpy's matrix class.
Comments
You can join all 0s and 1s of every row as strings and from there it's easy to get the integer representation. I had to convert the matrix to an array to get this to work, but maybe there is a straight solution:
import numpy as np
A = np.matrix([[0, 1, 1, 1, 0],
[1, 0, 1, 0, 1],
[0, 1, 0, 0, 1]])
B = np.asarray(A)
#join all 0/1s together as string and convert to integer
C = np.matrix([int(''.join(str(x) for x in column),2) for column in B]).reshape((B.shape[0],1))
print C
>>>
[[14]
[21]
[ 9]]