Aligning N-dimensional numpy arrays - python

I am putting data in numpy arrays for comparisons. They way the data is stored sometimes the dimensions are out of order. For example if the first array has the shape (10, 20, 30, 40), sometimes the second array will have the shape (10, 20, 40, 30). We can assume that the lengths of the dimensions will be unique.
Is there an easy way to convert the shape of the second array to the shape of the first without knowing the number of dimensions or the length of the dimensions beforehand? I think I can do it with a long series of elif statements and transpose operations, but I'm hoping there is a cleaner method available.

Use shape.index to find where each axis needs to be, then use transpose to re-order the axes:
import numpy as np
A = np.ones((10, 20, 40, 30))
B = np.ones((10, 20, 30, 40))
new_order = [A.shape.index(i) for i in B.shape]
B = B.transpose(new_order)

Related

Extend 1d numpy array in multiple dimensions

I have a 1d numpy array, e.g. a=[10,12,15] and I want to extend it so that I end up with a numpy array b with the shape (3,10,15,20) filled with a so that e.g. b[:,1,1,1] is [10,12,15].
I thought of using np.repeat but it's not clear to me how to do ?
tile will do it for you. Internally this does a repeat for each axis.
In [114]: a = np.array([10,12,15])
In [115]: A = np.tile(a.reshape(3,1,1,1),(1,10,15,20))
In [116]: A.shape
Out[116]: (3, 10, 15, 20)
In [117]: A[:,1,1,1]
Out[117]: array([10, 12, 15])
For some purposes it might be enough to just do the reshape and let broadcasting expand the dimensions as needed (without actually expanding memory use).
Code:
import numpy as np
a = np.arange(1800).reshape((10,12,15))
b = np.repeat(a, repeats=5, axis=0).reshape(((3,10,15,20)))
You can change axis if you want to repeat in a different fashion. To understand repeat use lower shape for e.g. a(3,5,4) and b (2,3,5,4) and repeat on different axis.

Flatten a tiled array

I have a tiled numpy array of shape (16, 32, 16, 16), that is each tile is 16x16 pixels in a grid 32 tiles wide and 16 high.
From here I want to reshape it to a 256 high x 512 wide 2D image, and I can't quite find the right incantation of splits, slices, and reshapes to get to what I want.
You can combine numpy's reshape and transpose to get this job done. I am not entirely sure which of the three "16"s belongs to the 32x16 repetition grid, but assuming it's the first one:
import numpy as np
data = np.random.random((16, 32, 16, 16))
# put number of repetitions next to respective dimension
transposed_data = np.transpose(data, (0, 2, 1, 3))
# concatenate repeated dimensions via reshape
reshaped_data = transposed_data.reshape((16 * 16, 32 * 16))
print(reshaped_data.shape)

How to calculate the sums of squares along one dimension of on ndarray?

One miltidimensional matrix with shape (2, 50, 25, 3):
xx = np.random.randn(2, 50, 25, 3)
I want to calculate the sum of squares of the last dimension. The result should be a matrix with a shape (2, 50, 25, 1).
[np.sum(x) for x in np.square(features_displacement[0][0][:])[:]]
This code can successfully calculate the one dimension, output a list with shape (25,1), but how can I calculate all the dimensions as described above?
You can apply the numpy functions along the axis you want, for example:
np.sum(np.square(xx), axis=3)
Will produce an array of shape (2, 50, 25). Not exactly sure this is what you want, if not please be more specific :-)
Use this:
sum_of_squares = np.sum(np.square(features_displacement), axis=-1)

Stack dimensions of numpy array

I have a numpy array of shape (2500, 16, 32, 24), and I want to make it into a ( something, 24) array, but I don't want numpy to shuffle my values. The 32 x 24 dimension at the end represent images and I want the corresponding elements to be consistent. Any ideas?
EDIT: Ok , I wasn't clear enough. (something, 24) = (1280000, 24).
Use arr.reshape(-1,arr.shape[-1]) or if you know it will be 24 arr.reshape(-1,24)

keeping track of indices change in numpy.reshape

While using numpy.reshape in Python, is there a way to keep track of the change in indices?
For example, if a numpy array with the shape (m,n,l,k) is reshaped into an array with the shape (m*n,k*l); is there a way to get the initial index ([x,y,w,z]) for the current [X,Y] index and vice versa?
Yes there is, it's called raveling and unraveling the index. For example you have two arrays:
import numpy as np
arr1 = np.arange(10000).reshape(20, 10, 50)
arr2 = arr.reshape(20, 500)
say you want to index the (10, 52) (equivalent to arr2[10, 52]) element but in arr1:
>>> np.unravel_index(np.ravel_multi_index((10, 52), arr2.shape), arr1.shape)
(10, 1, 2)
or in the other direction:
>>> np.unravel_index(np.ravel_multi_index((10, 1, 2), arr1.shape), arr2.shape)
(10, 52)
You don't keep track of it, but you can calculate it. The original m x n is mapped onto the new m*n dimension, e.g. n*x+y == X. But we can verify with a couple of multidimensional ravel/unravel functions (as answered by #MSeifert).
In [671]: m,n,l,k=2,3,4,5
In [672]: np.ravel_multi_index((1,2,3,4), (m,n,l,k))
Out[672]: 119
In [673]: np.unravel_index(52, (m*n,l*k))
Out[673]: (2, 12)

Categories

Resources