0

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.

asked Mar 30, 2015 at 9:07
1

3 Answers 3

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)
answered Mar 30, 2015 at 9:47
Sign up to request clarification or add additional context in comments.

2 Comments

Works (+1), but be warned: it only works as intended for values <256, because it packs the data in 8 bits. So if you have more columns than 8, you'll get back several columns rather than Mx1.
Ops, thank you for that @Oliver W., I didn't know it. I guess if the columns have some sort of structure (i.e. represent a 8, 16, 32, 64 or 128 bits integers) it could be fixed by adding p.view('u4') (for a 32 bit integer, similar for others). It would return a new view for the columns
1

You 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.

answered Mar 30, 2015 at 9:20

Comments

0

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]]
answered Mar 30, 2015 at 9:43

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.