numpy array to triangle (matrix) - python

I have an array that I want split int a matrix (10x10).
after a several tries i did this.
a=np.arange(1,56)
tri = np.zeros((10, 10))
tri[np.triu_indices_from(tri,0)]=a
tri
array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 0., 11., 12., 13., 14., 15., 16., 17., 18., 19.],
[ 0., 0., 20., 21., 22., 23., 24., 25., 26., 27.],
[ 0., 0., 0., 28., 29., 30., 31., 32., 33., 34.],
[ 0., 0., 0., 0., 35., 36., 37., 38., 39., 40.],
[ 0., 0., 0., 0., 0., 41., 42., 43., 44., 45.],
[ 0., 0., 0., 0., 0., 0., 46., 47., 48., 49.],
[ 0., 0., 0., 0., 0., 0., 0., 50., 51., 52.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 53., 54.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 55.]])
and the result I wish:
array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
[ 11., 12., 13., 14., 15., 16., 17., 18., 19., 0.],
[ 20., 21., 22., 23., 24., 25., 26., 27., 0., 0.],
[ 28., 29., 30., 31., 32., 33., 34., 0., 0., 0.],
[ 35., 36., 37., 38., 39., 40., 0., 0., 0., 0.],
[ 41., 42., 43., 44., 45., 0., 0., 0., 0., 0.],
[ 46., 47., 48., 49., 0., 0., 0., 0., 0., 0.],
[ 50., 51., 52., 0., 0., 0., 0., 0., 0., 0.],
[ 53., 54., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 55., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
I did several ties like try.T, np.triu, np.tril ...etc.
thanks

If this is what you mean, you can rotate an upper triangular index matrix by 90 degree using rot90() method and then use it as index to fill the values in the array:
import numpy as np
a=np.arange(1,56)
tri = np.zeros((10, 10))
tri[np.rot90(np.triu(np.ones((10,10), dtype=bool)))] = a
tri
# array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
# [ 11., 12., 13., 14., 15., 16., 17., 18., 19., 0.],
# [ 20., 21., 22., 23., 24., 25., 26., 27., 0., 0.],
# [ 28., 29., 30., 31., 32., 33., 34., 0., 0., 0.],
# [ 35., 36., 37., 38., 39., 40., 0., 0., 0., 0.],
# [ 41., 42., 43., 44., 45., 0., 0., 0., 0., 0.],
# [ 46., 47., 48., 49., 0., 0., 0., 0., 0., 0.],
# [ 50., 51., 52., 0., 0., 0., 0., 0., 0., 0.],
# [ 53., 54., 0., 0., 0., 0., 0., 0., 0., 0.],
# [ 55., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

Related

how to find percentage of similarity between two arrays

I have two data arrays x and y:
x = array([ 0., 0., 84., 80., 59., 22., 0., 0., 0., 0., 52.,
122., 117., 1., 10., 0., 0., 0., 0., 0., 0., 92.,
90., 74., 46., 0., 0., 0., 0., 28., 121., 117., 90.,
54., 0., 0., 0., 0., 0., 0., 47., 62., 54., 57.,
23., 63., 26., 62., 52., 138., 126., 98., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 19., 44., 74., 89., 119.,
77., 141., 137., 119., 0., 0., 0., 0., 91., 115., 89.,
143., 146., 45., 0., 0., 0., 65., 89., 1., 0., 0.,
0.])
y = array([ 0., 0., 79., 90., 64., 3., 0., 0., 0., 0., 19.,
113., 109., 1., 25., 0., 0., 0., 0., 0., 0., 90.,
99., 73., 35., 0., 0., 0., 0., 46., 106., 113., 105.,
52., 0., 0., 0., 0., 0., 0., 57., 68., 47., 20.,
0., 17., 1., 14., 48., 120., 118., 105., 0., 0., 0.,
0., 0., 0., 4., 1., 0., 0., 0., 42., 47., 80.,
86., 125., 121., 111., 16., 0., 0., 0., 47., 72., 112.,
123., 129., 82., 0., 0., 0., 87., 80., 0., 0., 5.,
0.])
I want to check the similarity between x and y in the program code. I've tried using SequenceMatcher() but I'm not sure about the similarity presentation results using that package. because when seeing the graph it has very similar, but the results of the presentation of the similarities are only 39.33%, so for me it's weird. is there another way to check the similarity between x and y data, if so, how and based on what kind of mathematical formula is used, thank you
my code for checking similarity using SequenceMatcher()
import difflib
from difflib import SequenceMatcher
sm=difflib.SequenceMatcher(None,x,y)
a = sm.ratio()*100
print('Similarity x and Testing y : ',round(a, 2),'%')
x and y graph:
Consider taking the Cross-Correlation function: https://en.wikipedia.org/wiki/Cross-correlation
Discussion:
Computing cross-correlation function?
Numpy implementation:
https://numpy.org/doc/stable/reference/generated/numpy.correlate.html

Python array: Take two and skip two

I have a case where I have input array like this below
array([[[ 1., 0., 2., 0., 3., 0., 4., 0., 5.],
[ 6., 0., 7., 0., 8., 0., 9., 0., 10.],
[11., 0., 12., 0., 13., 0., 14., 0., 15.]],
[[16., 0., 17., 0., 18., 0., 19., 0., 20.],
[21., 0., 22., 0., 23., 0., 24., 0., 25.],
[26., 0., 27., 0., 28., 0., 29., 0., 30.]]])
and I would like to get an output like the one below.
array([[[ 1., 0., 3., 0., 5.],
[ 6., 0., 8., 0., 10.],
[11., 0., 13., 0., 15.]],
[[16., 0., 18., 0., 20.],
[21., 0., 23., 0., 25.],
[26., 0., 28., 0., 30.]]])
I would love if the solution can be generic not just to this example.
Since the length of the last dimension cannot be guaranteed to be even, here I choose to build the bool indices:
>>> mask = np.arange(ar.shape[-1]) // 2 % 2 == 0 # np.arange() & 2 == 0 is faster
>>> mask
array([ True, True, False, False, True, True, False, False, True])
>>> ar[:, :, mask] # or ar[..., mask]
array([[[ 1., 0., 3., 0., 5.],
[ 6., 0., 8., 0., 10.],
[11., 0., 13., 0., 15.]],
[[16., 0., 18., 0., 20.],
[21., 0., 23., 0., 25.],
[26., 0., 28., 0., 30.]]])
If the length of the last dimension can be guaranteed to be even, reshape with slicing is another technique:
>>> ar
array([[[ 1., 0., 2., 0., 3., 0., 4., 0.],
[ 6., 0., 7., 0., 8., 0., 9., 0.],
[11., 0., 12., 0., 13., 0., 14., 0.]],
[[16., 0., 17., 0., 18., 0., 19., 0.],
[21., 0., 22., 0., 23., 0., 24., 0.],
[26., 0., 27., 0., 28., 0., 29., 0.]]])
>>> shape = ar.shape[:-1]
>>> ar.reshape(*shape, -1, 2)[..., ::2, :].reshape(*shape, -1)
array([[[ 1., 0., 3., 0.],
[ 6., 0., 8., 0.],
[11., 0., 13., 0.]],
[[16., 0., 18., 0.],
[21., 0., 23., 0.],
[26., 0., 28., 0.]]])

it there any way to convert 3D numpy array to 2D

I got a 3d NumPy array:
array([[[ 12., 0., 0.],
[ 15., 0., 0.],
[ 13., 0., 0.]],
[[ 12., 0., 0.],
[ 11., 0., 0.],
[ 13., 0., 0.]]])
Is there any way to convert to a 2d and only get
[12., 15., 13.]
[12., 11., 13.]
x = np.array(
[[[ 12., 0., 0.],
[ 15., 0., 0.],
[ 13., 0., 0.]],
[[ 12., 0., 0.],
[ 11., 0., 0.],
[ 13., 0., 0.]]]
)
x_2d = x[:, :, 0]
>> x_2d
>> array([[12., 15., 13.],
[12., 11., 13.]])

Differentiable affine transformation on patches of images in pytorch

I have a tensor of object bounding boxes, e.g. with the shape of [10,4] which correspond to a batch of images e.g. with shape [2,3,64,64] and transformation matrices for each object with shape [10,6] and a vector that defines which object index belongs to which image.
I would like to apply the affine transformations on patches of the images and replace those patches after applying the transformations. I am doing this using a for loop now, but the way I am doing it is not differntiable (I get the in place operation error from pytorch). I wanted to know if there is a differntiable way to do this. e.g. via grid_sample?
Here is my current code:
for obj_num in range(obj_vecs.shape[0]): #batch_size
im_id = obj_to_img[obj_num]
x1, y1, x2, y2 = boxes_pred[obj_num]
im_patch = img[im_id, :, x1:x2, y1:y2]
im_patch = im_patch[None, :, :, :]
img[im_id, :, x1:x2, y1:y2] = self.VITAE.stn(im_patch, theta_mean[obj_num], inverse=False)[0]
There are a few ways to perform differentiable crops in PyTorch.
Let's take a minimal example in 2D:
>>> x1, y1, x2, y2 = torch.randint(0, 9, (4,))
(tensor(7), tensor(3), tensor(5), tensor(6))
>>> x = torch.randint(0, 100, (9,9), dtype=float, requires_grad=True)
tensor([[18., 34., 28., 41., 1., 14., 77., 75., 23.],
[62., 33., 64., 41., 16., 70., 47., 45., 19.],
[20., 69., 5., 51., 1., 16., 20., 63., 52.],
[51., 25., 8., 30., 40., 67., 41., 27., 33.],
[36., 6., 95., 53., 69., 84., 51., 42., 71.],
[46., 72., 88., 82., 71., 75., 86., 36., 15.],
[66., 19., 58., 50., 91., 28., 7., 83., 4.],
[94., 50., 34., 34., 92., 45., 48., 97., 76.],
[80., 34., 19., 13., 77., 77., 51., 15., 13.]], dtype=torch.float64,
requires_grad=True)
Given x1, x2 (resp. y1, y2 the patch index boundaries on the height dimension (resp. width dimension). You can get the grid of coordinates corresponding do you patch using a combination of torch.arange and torch.meshgrid:
>>> sorted_range = lambda a, b: torch.arange(a, b) if b >= a else torch.arange(b, a)
>>> xi, yi = sorted_range(x1, x2), sorted_range(y1, y2)
(tensor([3, 4, 5, 6]), tensor([5]))
>>> i, j = torch.meshgrid(xi, yi)
(tensor([[3],
[4],
[5],
[6]]),
tensor([[5],
[5],
[5],
[5]]))
With that setup, you can extract and replace patches of x.
You can extract the patch by indexing x directly:
>>> patch = x[i, j].reshape(len(xi), len(yi))
tensor([[67.],
[84.],
[75.],
[28.]], dtype=torch.float64, grad_fn=<ViewBackward>)
Here is the mask for illustration purposes:
tensor([[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=torch.float64,
grad_fn=<IndexPutBackward>)
You can replace the values in x with the result from some transformation on the patch using torch.Tensor.index_put:
>>> values = 2*patch
tensor([[134.],
[168.],
[150.],
[ 56.]], dtype=torch.float64, grad_fn=<MulBackward0>)
>>> x.index_put(indices=(i, j), values=values)
tensor([[ 18., 34., 28., 41., 1., 14., 77., 75., 23.],
[ 62., 33., 64., 41., 16., 70., 47., 45., 19.],
[ 20., 69., 5., 51., 1., 16., 20., 63., 52.],
[ 51., 25., 8., 30., 40., 134., 41., 27., 33.],
[ 36., 6., 95., 53., 69., 168., 51., 42., 71.],
[ 46., 72., 88., 82., 71., 150., 86., 36., 15.],
[ 66., 19., 58., 50., 91., 56., 7., 83., 4.],
[ 94., 50., 34., 34., 92., 45., 48., 97., 76.],
[ 80., 34., 19., 13., 77., 77., 51., 15., 13.]],
dtype=torch.float64, grad_fn=<IndexPutBackward>)

Make 3D array with 1D arrays with zero padding depending on index of 1D array numpythonically

Consider the following 1D arrays
a=np.arange(3)+9
b=np.arange(3)+5
currently I am initializing the new 3d array by using
n=4
cols=3
k=np.vstack((a,b,a*b,np.zeros((n,cols)),a,b,a,a,b**2,np.zeros((n,cols)),a*2,a)).T.reshape(-1,2,n+5)
where a and b will always be the same shape
which results in
array([[[ 9., 5., 45., 0., 0., 0., 0., 9., 5.],
[ 9., 9., 25., 0., 0., 0., 0., 18., 9.]],
[[ 10., 6., 60., 0., 0., 0., 0., 10., 6.],
[ 10., 10., 36., 0., 0., 0., 0., 20., 10.]],
[[ 11., 7., 77., 0., 0., 0., 0., 11., 7.],
[ 11., 11., 49., 0., 0., 0., 0., 22., 11.]]])
How would i use a similar technique, also without a for loop, to change the zero padding to the following:
array([[[ 9., 5., 45., 9., 5., 0., 0., 0., 0.],
[ 9., 9., 25., 18., 9., 0., 0., 0., 0.]],
[[ 10., 6., 60., 0., 0., 10., 6., 0., 0.],
[ 10., 10., 36., 0., 0., 20., 10., 0., 0.]],
[[ 11., 7., 77., 0., 0., 0., 0., 11., 7.],
[ 11., 11., 49., 0., 0., 0., 0., 22., 11.]]])
One can use advanced-indexing to assign those array values into a zeros initialized array given the column indices -
out = np.zeros((3,2,9),dtype=bool)
vals = np.array([[a,b,a*b,a,b],[a,a,b**2,2*a,a]])
out[np.arange(3)[:,None],:, idx] = vals.T
Sample run -
In [448]: a
Out[448]: array([ 9, 10, 11])
In [449]: b
Out[449]: array([5, 6, 7])
In [450]: out
Out[450]:
array([[[ 9., 5., 45., 9., 5., 0., 0., 0., 0.],
[ 9., 9., 25., 18., 9., 0., 0., 0., 0.]],
[[ 10., 6., 60., 0., 0., 10., 6., 0., 0.],
[ 10., 10., 36., 0., 0., 20., 10., 0., 0.]],
[[ 11., 7., 77., 0., 0., 0., 0., 11., 7.],
[ 11., 11., 49., 0., 0., 0., 0., 22., 11.]]])

Categories