I have a large numpy array with increasing elements as follows
A = [512,2560,3584,5632,....]
Elements are always spaced at least 1024 apart
Let's say I need to transform that above array to the one below, where for each element of the original matrix A, I take a range of values from A[n] to A[n]+1024 (in steps of one) and those become the values of a new matrix as follows
A2 = [512,513,514,...,1535,2560,2561,2562,...3583,....]
The way I've set up the problem is to loop through the original matrix A, generate a range of values between A[0] and A[0]+1024 (for example), allocate them to a new array and so on. Code below. Convention is for A as the original seed matrix
seed = 0
A2 = np.empty(len(A)*1024,)
for ind in range(len(A)):
A2[seed:seed+1024] = np.arange(A[ind],A[ind]+1024)
seed = seed+1024;
I get the answer I need, but I'm wondering if that is the best way to do this. I'm a matlab user transitioning to using python and numpy, and I'm not used to optimizing numpy yet. I appreciate any help.
You can use broadcasting -
(A[:,None] + np.arange(1024)).ravel()
Sample run -
# Input array
In [433]: A = np.array([512,2560,3584,5632])
# Add ranged numbers in a broadcasted way for elementwise addition
In [434]: A[:,None] + np.arange(1024)
Out[434]:
array([[ 512, 513, 514, ..., 1533, 1534, 1535],
[2560, 2561, 2562, ..., 3581, 3582, 3583],
[3584, 3585, 3586, ..., 4605, 4606, 4607],
[5632, 5633, 5634, ..., 6653, 6654, 6655]])
# Finally flatten those for final output
In [435]: (A[:,None] + np.arange(1024)).ravel()
Out[435]: array([ 512, 513, 514, ..., 6653, 6654, 6655])
Alternatively with np.add.outer -
np.add.outer(A,range(1024)).ravel()
Equivalent MATLAB version :
For reference, the MATLAB version to leverage the equivalent broadcasting with bsxfun and keeping in mind the column-major ordering, would look something along these lines -
>> A = [512,2560,3584,5632];
>> sums = bsxfun(@plus, A, [0:1023].');
>> [sums(1:3,1) ; sums(end-2:end,1)].'
ans =
512 513 514 1533 1534 1535
>> [sums(1:3,2) ; sums(end-2:end,2)].'
ans =
2560 2561 2562 3581 3582 3583
>> [sums(1:3,3) ; sums(end-2:end,3)].'
ans =
3584 3585 3586 4605 4606 4607
>> [sums(1:3,4) ; sums(end-2:end,4)].'
ans =
5632 5633 5634 6653 6654 6655
>> out = reshape(sums,1,[]);
>> [out(1:3) out(end-2:end)]
ans =
512 513 514 6653 6654 6655
You can use:
(A.reshape(-1,1) + numpy.arange(1024)).reshape(-1)
This works as follows:
reshape(-1,1) to obtain an n×1 array;If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With