Reputation: 23
I am a Matlab user, and trying to move into Python. I tried to code a minimal example of de2bi
function (which converts a decimal into binary as right-msb) in Python which I had before in Matlab. But, I am confused with numpy arrays.
Python code:
import numpy as np
def de2bi(d, n)
d = np.array(d)
power = 2**np.arange(n)
d = d * np.ones((1,n))
b = np.floor((d%(2*power))/power)
return b
Python output:
>>> print(de2bi(13,8))
[[ 1. 0. 1. 1. 0. 0. 0. 0.]]
print(de2bi([13,15],8)) #This line fails
Matlab code:
function b = d2b( d, n )
d = d(:);
power = ones(length(d), 1)*(2.^(0 : n-1));
d = d * ones(1, n);
b = floor(rem(d, 2*power)./power);
end
Matlab output:
>> d2b(13,8)
ans =
1 0 1 1 0 0 0 0
>> d2b([13,15],8)
ans =
1 0 1 1 0 0 0 0
1 1 1 1 0 0 0 0
Matlab code is working both for integer inputs and array of integers. But python code works for integer inputs, but keeps failing for arrays. How to manage operations both for integers and integer arrays in Python automatically? It may be a very easy question, excuse me, but I am a very newbie in python.
Thanks in advance.
Upvotes: 2
Views: 1323
Reputation: 231395
Does this help?
In [439]: d=np.array([13,15])
In [440]: power=np.ones((d.shape[0],1))*(2**np.arange(8))
In [441]: power
Out[441]:
array([[ 1., 2., 4., 8., 16., 32., 64., 128.],
[ 1., 2., 4., 8., 16., 32., 64., 128.]])
In [442]: np.floor((d[:,None]%(2*power))/power)
Out[442]:
array([[ 1., 0., 1., 1., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 0., 0., 0., 0.]])
we don't even need the ones
:
In [443]: power = 2**np.arange(8)
In [444]: np.floor((d[:,None]%(2*power))/power)
Out[444]:
array([[ 1., 0., 1., 1., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 0., 0., 0., 0.]])
When broadcasting d
against power
, the dimension expansion for power
is automatic: d[:,None]%(2*power[None,:])
. The ones
in MATLAB accomplish the same dimension expansion (to (2,8) shaped arrays).
May want to start with d=np.atleast_1d(d)
, so it treats the scalar case like a 1 element array. We could refine things so it returns a 1d array when given a scalar, and 2d when given a list or 1d array. In MATLAB everything is 2d or higher.
Better yet, use ellipsis
when expanding d
. Then d can be 0d, 1d, or even nd.
np.floor((d[...,None]%(2*power))/power)
Upvotes: 0
Reputation: 524
Your problem is with the multiplication: d = d * np.ones((1,n))
. NumPy attemps to perform an element-wise multiplication, which would fail because of dimension mismatch (your ones array has only one row). When d is scalar though, NumPy can infer that you mean multiply to scalar, hence the code would run.
What you really want to do (as I understand) is to expand each element to an n-length row. A possible solution would be to create an intermediate array to hold the new values, since the size of an array is not changeable:
def d2b(d, n):
d = np.array(d)
d = np.reshape(d, (1, -1))
power = np.flipud(2**np.arange(n))
g = np.zeros((np.shape(d)[1], n))
for i, num in enumerate(d[0]):
g[i] = num * np.ones((1,n))
b = np.floor((g%(2*power))/power)
return b
Upvotes: 1