How to flip half of a numpy array - python

I have a numpy array:
arr=np.array([[1., 2., 0.],
[2., 4., 1.],
[1., 3., 2.],
[-1., -2., 4.],
[-1., -2., 5.],
[1., 2., 6.]])
I want to flip the second half of this array upward. I mean I want to have:
flipped_arr=np.array([[-1., -2., 4.],
[-1., -2., 5.],
[1., 2., 6.],
[1., 2., 0.],
[2., 4., 1.],
[1., 3., 2.]])
When I try this code:
fliped_arr=np.flip(arr, 0)
It gives me:
fliped_arr= array([[1., 2., 6.],
[-1., -2., 5.],
[-1., -2., 4.],
[1., 3., 2.],
[2., 4., 1.],
[1., 2., 0.]])
In advance, I do appreciate any help.

You can simply concatenate rows below the nth row (included) with np.r_ for instance, with row index n of your choice, at the top and the other ones at the bottom:
import numpy as np
n = 3
arr_flip_n = np.r_[arr[n:],arr[:n]]
>>> array([[-1., -2., 4.],
[-1., -2., 5.],
[ 1., 2., 6.],
[ 1., 2., 0.],
[ 2., 4., 1.],
[ 1., 3., 2.]])

you can do this by slicing the array using the midpoint:
ans = np.vstack((arr[int(arr.shape[0]/2):], arr[:int(arr.shape[0]/2)]))
to break this down a little:
find the midpoint of arr, by finding its shape, the first index of which is the number of rows, dividing by two and converting to an integer:
midpoint = int(arr.shape[0]/2)
the two halves of the array can then be sliced like so:
a = arr[:midpoint]
b = arr[midpoint:]
then stack them back together using np.vstack:
ans = np.vstack((a, b))
(note vstack takes a single argument, which is a tuple containing a and b: (a, b))

You can do this with array slicing and vstack -
arr=np.array([[1., 2., 0.],
[2., 4., 1.],
[1., 3., 2.],
[-1., -2., 4.],
[-1., -2., 5.],
[1., 2., 6.]])
mid = arr.shape[0]//2
np.vstack([arr[mid:],arr[:mid]])
array([[-1., -2., 4.],
[-1., -2., 5.],
[ 1., 2., 6.],
[ 1., 2., 0.],
[ 2., 4., 1.],
[ 1., 3., 2.]])

Related

What is Pytorch equivalent of Pandas groupby.apply(list)?

I have the following pytorch tensor long_format:
tensor([[ 1., 1.],
[ 1., 2.],
[ 1., 3.],
[ 1., 4.],
[ 0., 5.],
[ 0., 6.],
[ 0., 7.],
[ 1., 8.],
[ 0., 9.],
[ 0., 10.]])
I would like to groupby the first column and store the 2nd column as a tensor. The result is NOT guranteed to be the same size for each grouping. See example below.
[tensor([ 1., 2., 3., 4., 8.]),
tensor([ 5., 6., 7., 9., 10.])]
Is there any nice way to do this using purely Pytorch operators? I would like to avoid using for loops for tracebility purposes.
I have tried using a for loop and empty list of empty tensors but this result in an incorrect trace (different inputs values gave same results)
n_groups = 2
inverted = [torch.empty([0]) for _ in range(n_groups)]
for index, value in long_format:
value = value.unsqueeze(dim=0)
index = index.int()
if type(inverted[index]) != torch.Tensor:
inverted[index] = value
else:
inverted[index] = torch.cat((inverted[index], value))
You can use this code:
import torch
x = torch.tensor([[ 1., 1.],
[ 1., 2.],
[ 1., 3.],
[ 1., 4.],
[ 0., 5.],
[ 0., 6.],
[ 0., 7.],
[ 1., 8.],
[ 0., 9.],
[ 0., 10.]])
result = [x[x[:,0]==i][:,1] for i in x[:,0].unique()]
output
[tensor([ 5., 6., 7., 9., 10.]), tensor([1., 2., 3., 4., 8.])]

Convert multiple arrays to single array with new dimension

I have 4 different numpy array's (2Dimension) and each array have the size (112,20).
How can I convert (concatenate) them, to one array with 3 Dimension and the size of (112, 20, 4).
Thanks for your support!
Use np.stack((arr1, arr2, arr3, arr4), axis=2):
arr1 = np.zeros((2,5))
arr2 = np.ones((2,5))
arr3 = np.ones((2,5))*2
arr4 = np.ones((2,5))*3
v = np.stack((arr1, arr2, arr3, arr4), axis=2)
v.shape returns (2, 5, 4)
Output:
array([[[0., 1., 2., 3.],
[0., 1., 2., 3.],
[0., 1., 2., 3.],
[0., 1., 2., 3.],
[0., 1., 2., 3.]],
[[0., 1., 2., 3.],
[0., 1., 2., 3.],
[0., 1., 2., 3.],
[0., 1., 2., 3.],
[0., 1., 2., 3.]]])

Checking non zero-sum rows in numpy array and removing them

I have a numpy array like this:
array([[ 3., 2., 3., ..., 0., 0., 0.],
[ 3., 2., -4., ..., 0., 0., 0.],
[ 3., -4., 1., ..., 0., 0., 0.],
...,
[-1., -2., 4., ..., 0., 0., 0.],
[ 4., -2., -2., ..., 0., 0., 0.],
[-2., 2., 4., ..., 0., 0., 0.]], dtype=float32)
what I want to do is removing all the rows that do not sum to zero and remove them, while also saving such rows indexes/positions in order to eliminate them to another array.
I'm trying the following:
for i in range(len(arr1)):
count=0
for j in arr1[i]:
count+=j
if count != 0:
arr_1 = np.delete(arr1,i,axis=0)
arr_2 = np.delete(arr2,i,axis=0)
the resulting arr_1 and arr_2 still contain rows that do not sum to zero. What am I doing wrong?
You can compute sum then keep row that have sum == 0 like below:
a=np.array([
[ 3., 2., 3., 0., 0., 0.],
[ 3., 2., -4., 0., 0., 0.],
[ 3., -4., 1., 0., 0., 0.]])
b = a.sum(axis=1)
# array([8., 1., 0.])
print(a[b==0])
Output:
array([[ 3., -4., 1., 0., 0., 0.]])
Just use sum(axis=1):
mask = a.sum(axis=1) != 0
do_sum_to_0 = a[~mask]
dont_sum_to_0 = a[mask]

Calculate saturated values after clipping in Theano

I am using theano.clip to limit values of my numpy array. For e.g.
array = np.array([[ 1., -1., -3., 1., 1.],
[ 3., -4., -5., 0., -1.],
[ 8., -3., -7., -3., -3.],
[ 8., 2., -2., -3., -3.],
[ 7., 0., 0., 1., 0.]])
max_val = np.array([2.0]).astype('float32')
T.clip(array, -max_val, max_val).eval()
Output:
array([[ 1., -1., -2., 1., 1.],
[ 2., -2., -2., 0., -1.],
[ 2., -2., -2., -2., -2.],
[ 2., 2., -2., -2., -2.],
[ 2., 0., 0., 1., 0.]])
I want to calculate how many values were clipped after the clipping operation. Is it possible?
Here's one approach with np.count_nonzero on a mask of values beyond the limits computed with comparison against the min and max limits -
np.count_nonzero((array < -max_val) | (array > max_val))
np.count_nonzero is meant for performance, as it operates on a mask/boolean array to get the total count pretty efficiently.
Alternatively, a shorter version using absolute values as the min and max limits as in this case they are just negative and positive values of the same limiting number -
np.count_nonzero(np.abs(array) > max_val)
Sample run -
In [267]: array
Out[267]:
array([[ 1., -1., -3., 1., 1.],
[ 3., -4., -5., 0., -1.],
[ 8., -3., -7., -3., -3.],
[ 8., 2., -2., -3., -3.],
[ 7., 0., 0., 1., 0.]])
In [268]: max_val = np.array([2.0]).astype('float32')
In [269]: np.count_nonzero((array < -max_val) | (array > max_val))
Out[269]: 13
In [270]: np.count_nonzero(np.abs(array) > max_val)
Out[270]: 13
If your array's name is a, you can do
np.logical_or(a >= 1, a <= -1).sum()
You won't count elements twice, since - max_val < max_val. However, this requires two passes on a.

Putting multiple columns into callable sub arrays python

I have a set of data which is in columns, where the first column is the x values. How do i read this in?
If you want to store both, x and y values you can do
ydat = np.zeros((data.shape[1]-1,data.shape[0],2))
# write the x data
ydat[:,:,0] = data[:,0]
# write the y data
ydat[:,:,1] = data[:,1:].T
Edit:
If you want to store only the y-data in the sub arrays you can simply do
ydat = data[:,1:].T
Working example:
t = np.array([[ 0., 0., 1., 2.],
[ 1., 0., 1., 2.],
[ 2., 0., 1., 2.],
[ 3., 0., 1., 2.],
[ 4., 0., 1., 2.]])
a = t[:,1:].T
a
array([[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2.]])

Categories