How do you sequentially flip each dimension in a NumPy array? - python

I have encountered the following function in MATLAB that sequentially flips all of the dimensions in a matrix:
function X=flipall(X)
for i=1:ndims(X)
X = flipdim(X,i);
end
end
Where X has dimensions (M,N,P) = (24,24,100). How can I do this in Python, given that X is a NumPy array?

The equivalent to flipdim in MATLAB is flip in numpy. Be advised that this is only available in version 1.12.0.
Therefore, it's simply:
import numpy as np
def flipall(X):
Xcopy = X.copy()
for i in range(X.ndim):
Xcopy = np.flip(Xcopy, i)
return Xcopy
As such, you'd simply call it like so:
Xflip = flipall(X)
However, if you know a priori that you have only three dimensions, you can hard code the operation by simply doing:
def flipall(X):
return X[::-1,::-1,::-1]
This flips each dimension one right after the other.
If you don't have version 1.12.0 (thanks to user hpaulj), you can use slice to do the same operation:
import numpy as np
def flipall(X):
return X[[slice(None,None,-1) for _ in X.shape]]

Related

How to use numpy.eye function with custom diagonal values?

I am trying to use a single line of code to make a matrix with zeros except a custom value for the diagonals. I am able to do it like the code I put below, but am wondering if I can do it by only using np.eye?
import numpy as np
a = np.eye(4,4 k=0)
np.fill_diagonal (a,4)
print(a)
try the identity matrix in numpy module:
a=np.identity(10)*4
import numpy as np
a = np.eye(4)*4
print(a)
I would avoid np.eye() altogether and just use np.fill_diagonal() on a zeroed matrix, if you are not using any of its features:
import numpy as np
def value_eye_fill(value, n):
result = np.zeros((n, n))
np.fill_diagonal(result, value)
return result
That should be the fastest approach for larger inputs, within NumPy.
Of course you can also use np.eye() and avoid np.fill_diagonal() by just multiplying the value by the result of np.eye():
import numpy as np
def value_eye_fill(value, n):
return value * np.eye(n)

How can I randomly apply rotation and flip to arrays in a list of using python?

I have a list of NumPy arrays, I want to apply rot90 and flip function randomly on it. So that in the end, I have a list where some arrays are as it is, and some are modified (with that two fuctions).
I directly pass that list of arrays to numpy.random.choice, it gives me the following error ValueError: a must be 1-dimensional.
thanks in advance.
One approach it to create a population of functions and pick randomly, using random.choice, the one to apply to each image:
import random
import numpy as np
# for reproducibility
random.seed(42)
np.random.seed(42)
# toy data representing the list of images
images = [np.random.randint(255, size=(128, 128)) for _ in range(10)]
functions = [lambda x: x, np.rot90, np.flip]
# pick function at random at apply to image
res = [random.choice(functions)(image) for image in images]
You can just sample indices and apply to the array at the respecting index. So here is an example of the basic idea:
import numpy as np
# generate some random list of arrays
l = [np.random.randint(0,10,(4,4)) for _ in range(10)]
# sample indices and apply rotation and flip
indices = np.random.choice(np.arange(len(l)),int(len(l)/2),replace=False)
new_l = [np.flip(np.rot90(l[i])) if i in indices else l[i] for i in range(len(l))]
Why don't you sample a list of indeces that needs to be modified?
In the following example, I have set:
A list of functions which could be applied transformations
If functions can be applied to the same only once (apply_only_once=True), or multiple applications are permitted (apply_only_once=False)
Number of lines which must be modified is n_lines_to_modify. Clearly, if apply_ony_once=True, n_lines_to_modify must be less or equal to the number of rows in the array; note that, if apply_only_once=False, n_lines_to_modify is not constrained, because multiple transformation can be applied to the same line (corner case: all the transformations applied to one line only!)
arrays is just a test input
In code:
import random
import numpy as np
transformations = [lambda x: x**2, lambda x: x+2]
apply_only_once = True
n_lines_to_modify = 2
arrays = np.array([np.array([1,2,3]), np.array([1,2,3]), np.array([3,4,5])])
if apply_only_once:
to_be_modified = random.sample(range(len(arrays)), n_lines_to_modify)
else:
to_be_modified = [random.choice(range(len(arrays))) for _ in range(n_lines_to_modify)]
for i in to_be_modified:
arrays[i] = random.choice(transformations)(arrays[i])
print(arrays)

How to subtrac a numpy array element-by-elemnt by another numpy array

I have two numpy arrays, with just the 3-dimensional coordinates of two molecules.
I need to implement the following equation, and I'm having problems in the subtraction of each coordinate of one of the arrays by the second, and then square it.
I have tried the following, but since I'm still learning I feel that I am making some major mistake. The simple code I use is:
a = [math.sqrt(1/3*((i[:,0]-j[:,0])**2) + ((i[:,1] - j[:,1])**2) + ((i[:,2]-j[:,2])**2) for i, j in zip(coordenates_2, coordenates_1))]
It's numpy you can easily do it using the following example:
import numpy as np
x1 = np.random.randn(3,3,3)
x2 = np.random.randn(3,3,3)
res = np.sqrt(np.mean(np.power(x1-x2,2)))

How to form a sequence of consecutive numbers in Pytorch?

How to convert the Matlab code
v = [1: n]
to pytorch?
Writing a whole loop for that seems inefficient.
You can directly use the arange method from Pytorch.
torch_v = torch.arange(1,n)
Reference: https://pytorch.org/docs/master/torch.html?highlight=arange#torch.arange
You form a sequence of consecutive numbers in python
import numpy as np
v= np.arange(1,n)
if you want a torch tensor you can transform the numpy array like this:
torch_v = torch.from_numpy(v)

pointwise operations on scipy.sparse matrices

Is it possible to apply for example numpy.exp or similar pointwise operators to all elements in a scipy.sparse.lil_matrix or another sparse matrix format?
import numpy
from scipy.sparse import lil_matrix
x = numpy.ones((10,10))
y = numpy.exp(x)
x = lil_matrix(numpy.ones((10,10)))
# y = ????
numpy.exp(x) or scipy.exp(x) yields an AttributeError, and numpy.exp(x.data) yields the same.
thanks!
I do not know the full details, but converting to another type works, at least when using the array of non zero elements:
xcsc = x.tocsc()
numpy.exp(xcsc.data) # works

Categories

Resources