Struggling to reshape an odd array - python

I am struggling with a problem from my python class that has been assigned where I have to create a 1D array with the arange function from 0 to 29. Then reshape it into:
An array of rank 2 of the appropriate size.
An array of rank 3 of the appropriate size.
I am able to create the array with z = np.arange(29), however I am unable to reshape it to be a 2d/3d array.
z = np.arange(29)
print(z.shape)
z = z.reshape(2,14)
But then I get an error saying:
ValueError:cannot reshape array of size 29 into shape (2,14)

While the specification is a bit ambiguous, I suspect they want you to generate 30 numbers that include 0 and 29:
In [73]: arr = np.arange(30)
In [74]: arr
Out[74]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
In [75]: arr.shape
Out[75]: (30,)
There many ways you can reshape this, all of which assume 30 values:
In [76]: arr.reshape(2,15)
Out[76]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
[15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
In [77]: arr.reshape(3,10)
Out[77]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
In [79]: arr.reshape(2,3,5)
Out[79]:
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]],
[[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]]])

Proposed solution based on comments.
Assumption is the that the array should include the numbers from 0 to 28, but it doesn't necessarily have to be of size 29. This allows us to add np.nan as the 30th element allowing the reshape.
import numpy as np
x = np.arange(29)
x = np.append(x, np.nan)
print(x.shape)
y = x.reshape(15, 2)
print(y.shape)
z = x.reshape(5, 3, 2)
print(z.shape)
output:
(30,)
(15, 2)
(5, 3, 2)

Related

Python - dask: calling map_blocks and returning a new dimension error

I am calling map_blocks with an 1d array and returning a 2d array as follows.
def compute(i):
return np.array([i + 1, i + 2])
a = da.arange(30, chunks=10, dtype = np.uint64)
x = da.map_blocks(compute, a, dtype=a.dtype, new_axis=1, chunks=(6,10))
x.compute()
Which outputs this:
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
[12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
[22, 23, 24, 25, 26, 27, 28, 29, 30, 31]], dtype=uint64)
If I change the last line to x[1].compute() I get the correct answer array([ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], dtype=uint64).
However, if I try to access any subarray that belongs to any other chunk, for instance x[2].compute() I get IndexError: index 2 is out of bounds for axis 0 with size 2.
Using x[2].visualize() I see what seems to be the error: dask is trying to get that subarray from the wrong chunk as shown below (it should call getitem from the middle one):
Am I doing anything wrong? Perhaps messing with either new_axis or chunks parameters. I have no clue. Thanks in advance!

split 3D numpy to 3 diffrent arrays

I have numpy.array pf shape (64 , 64 , 64)
I would like to split it on to 3 variables ,so
x.shape ==> (64)
y.shape ==> (64)
z.shape ==> (64)
as each dim represent voxels coordinate (x,y,z) , I tried use dsplit() but no luck. any suggestion?
What you're looking for is probably transpose + ravel:
X = np.arange(27).reshape((3,3,3))
>>> X
([[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]],
[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]]])
Your x,y,z:
>>> X.transpose((0,1,2)).ravel()
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26])
>>> X.transpose((1,2,0)).ravel()
array([ 0, 9, 18, 1, 10, 19, 2, 11, 20, 3, 12, 21, 4, 13, 22, 5, 14,
23, 6, 15, 24, 7, 16, 25, 8, 17, 26])
>>> X.transpose((2,0,1)).ravel()
array([ 0, 3, 6, 9, 12, 15, 18, 21, 24, 1, 4, 7, 10, 13, 16, 19, 22,
25, 2, 5, 8, 11, 14, 17, 20, 23, 26])

Swaping columns of numpy array in all rows but the first one

Given a numpy array
import numpy as np
a = np.arange(4*7).reshape([4, 7])
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27]])
I can apply slicing to swap the second and third columns by:
a[:, [0, 2, 1, 3, 4, 5, 6]]
array([[ 0, 2, 1, 3, 4, 5, 6],
[ 7, 9, 8, 10, 11, 12, 13],
[14, 16, 15, 17, 18, 19, 20],
[21, 23, 22, 24, 25, 26, 27]])
But, can I use slices to swap the second and third columns for all rows but the first one? The expected output would be:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 9, 8, 10, 11, 12, 13],
[14, 16, 15, 17, 18, 19, 20],
[21, 23, 22, 24, 25, 26, 27]])
For in-situ edit, we can use flipping after slicing out the two columns -
a[1:,1:3] = a[1:,2:0:-1]
Sample run -
In [556]: a = np.arange(4*7).reshape([4, 7])
In [557]: a
Out[557]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27]])
In [559]: a[1:,1:3] = a[1:,2:0:-1]
In [560]: a
Out[560]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 9, 8, 10, 11, 12, 13],
[14, 16, 15, 17, 18, 19, 20],
[21, 23, 22, 24, 25, 26, 27]])
For columns that are two-step apart, use a stepsize of 2 to assign (LHS) and -2 to select (RHS). Hence, for column IDs 1 & 3 -
In [577]: a = np.arange(4*7).reshape([4, 7])
In [578]: a
Out[578]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27]])
In [579]: a[1:,1:4:2] = a[1:,3:0:-2]
In [580]: a
Out[580]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 10, 9, 8, 11, 12, 13],
[14, 17, 16, 15, 18, 19, 20],
[21, 24, 23, 22, 25, 26, 27]])
Another method would be with explicit column numbered indexing -
a[1:,[1,2]] = a[1:,[2,1]]
Note that this creates a copy with a[1:,[2,1]] and as such would be less memory efficient than the first method.

give a shape to a numpy array create from simple list

I have a list of number
mylist = [0, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]
i converted mylist in a numpy array
import numpy as np
mylist_np = np.array(mylist)
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
i wish to give a shape to the array as:
array([[0, 1,2,3,4,5,6,7,8,9],
[10,11,12,13,14,15,16,17,18,19],
[20,21,22,23,24,25,26,27,28,29]])
Numpy does not support ragged arrays (at least, not without breaking the results of some fundamental methods)
If your array was
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
Then it could be reshaped by:
np.reshape(mylist_np, (3,10))
But why use numpy? You can shape your array when you set it up with something like:
my_list = [range(max(a,1),a+10) for a in range(0,30,10)]

Efficient Numpy sampling of subarray in a wrapped 2D array

I have a 4x4 array and wonder if there's a way to randomly sample a 2x2 square from it at any location, allowing for the square to wrapped around when it reaches an edge.
For example:
>> A = np.arange(16).reshape(4,-1)
>> start_point = A[0,3]
start_point = 3
the square would be [[15, 12], [3,0]]
I've generalized (a little...) my answer, permitting a rectangular input array
and even a rectangular random sample
def rand_sample(arr, nr, nc):
"sample a nr x nc submatrix starting from a random element of arr, with wrap"
r, c = arr.shape
i, j = np.random.randint(r), np.random.randint(c)
r = np.arange(i, i+nr) % r
c = np.arange(j, j+nc) % c
return arr[r][:,c]
You may want to check that arr is a 2D array
You could use np.lib.pad with 'wrap' option to have a padded version of the input array that has wrapped around elements at the end along the rows and columns. Finally, index into the padded array to get the desired output. Here's the implementation -
import numpy as np
# Input array and start row-col indices and neighbourhood extent
A = np.arange(42).reshape(6,-1)
start_pt = [0,3] # start_point
N = 5 # neighbourhood extent
# Pad boundary with wrapped elements
A_pad = np.lib.pad(A, ((0,N-1),(0,N-1)), 'wrap')
# Final output after indexing into padded array
out = A_pad[start_pt[0]:start_pt[0]+N,start_pt[1]:start_pt[1]+N]
Sample run -
In [192]: A
Out[192]:
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33, 34],
[35, 36, 37, 38, 39, 40, 41]])
In [193]: start_pt
Out[193]: [0, 3]
In [194]: A_pad
Out[194]:
array([[ 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3],
[ 7, 8, 9, 10, 11, 12, 13, 7, 8, 9, 10],
[14, 15, 16, 17, 18, 19, 20, 14, 15, 16, 17],
[21, 22, 23, 24, 25, 26, 27, 21, 22, 23, 24],
[28, 29, 30, 31, 32, 33, 34, 28, 29, 30, 31],
[35, 36, 37, 38, 39, 40, 41, 35, 36, 37, 38],
[ 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3],
[ 7, 8, 9, 10, 11, 12, 13, 7, 8, 9, 10],
[14, 15, 16, 17, 18, 19, 20, 14, 15, 16, 17],
[21, 22, 23, 24, 25, 26, 27, 21, 22, 23, 24]])
In [195]: out
Out[195]:
array([[ 3, 4, 5, 6, 0],
[10, 11, 12, 13, 7],
[17, 18, 19, 20, 14],
[24, 25, 26, 27, 21],
[31, 32, 33, 34, 28]])

Categories