Converting 3D matrix to cascaded 2D Matrices - python

I have a 3D matrix in python as the following:
import numpy as np
a = np.ones((2,2,3))
a[0,0,0] = 2
a[0,0,1] = 3
a[0,0,2] = 4
I want to convert this 3D matrix to a set of 2D matrices. I have tried np.reshape but it did not solve my problem. The final shape I am interested in is the following cascaded vesrsion:
[[ 2. 1. 3. 1. 4. 1.]
[ 1. 1. 1. 1. 1. 1.]]
However, np.reshape gives me the following
[[ 2. 3. 4. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1.]]
How can I solve this?

Use transpose alongwith reshape -
a.transpose([0,2,1]).reshape(a.shape[0],-1)
Or use swapaxes that does the same job as transpose alongwith reshape -
a.swapaxes(2,1).reshape(a.shape[0],-1)
Sample run -
In [66]: a
Out[66]:
array([[[ 2., 3., 4.],
[ 1., 1., 1.]],
[[ 1., 1., 1.],
[ 1., 1., 1.]]])
In [67]: a.transpose([0,2,1]).reshape(a.shape[0],-1)
Out[67]:
array([[ 2., 1., 3., 1., 4., 1.],
[ 1., 1., 1., 1., 1., 1.]])
In [68]: a.swapaxes(2,1).reshape(a.shape[0],-1)
Out[68]:
array([[ 2., 1., 3., 1., 4., 1.],
[ 1., 1., 1., 1., 1., 1.]])

Related

How to find mean of each two rows of a numpy array

I have a big numpy array and want to take the mean of the second columns of each two rows and save the array as a new one. I want to take the mean of each two row, i.e. the mean of second column of of rows 1 and 2. Then, mean of second column of rows 3 and 4, and so on. Then, I want to merge each two rows as a single one. First and third columns of this paired rows are also the same. This is my simplified array:
input= np.array ([[1., 2., 5.],
[1., 4., 5.],
[4., 10., 3.],
[4., 2., 3.],
[1., 0., 0.],
[1., 1., 0.]])
Then, I want to get:
output= np.array ([[1., 3., 5.],
[4., 6., 3.],
[1., 0.5, 0.]])
I tried the following but it was not successful at all:
output=np.array([])
for i in range (len(input)-1):
g=(input[i,1]+input[i+1,1])/2
output=np.append(g,output)
In advance, I do appreciate any help.
For two rows, I find it easier to do:
(arr[::2] + arr[1::2])/2
A little more robust method for reshape, using the input shape
i= np.array ([[1., 2., 5.],
[1., 4., 5.],
[4., 10., 3.],
[4., 2., 3.],
[1., 0., 0.],
[1., 1., 0.]])
i.reshape(-1, 2, i.shape[-1]).mean(1)
array([[1. , 3. , 5. ],
[4. , 6. , 3. ],
[1. , 0.5, 0. ]])
You could reshape and find the mean, as follows:
import numpy as np
ipt = np.array([[1., 2., 5.],
[1., 4., 5.],
[4., 10., 3.],
[4., 2., 3.],
[1., 0., 0.],
[1., 1., 0.]])
result = np.mean(ipt.reshape((3, 2, 3)), axis=1)
print(result)
Output
[[1. 3. 5. ]
[4. 6. 3. ]
[1. 0.5 0. ]]
As a side note, avoid using input as a variable name as it shadows the built-in input.
Take even rows (ipt[::2]), odd rows (ipt[1::2]), add them and divide by 2:
output = (ipt[::2] + ipt[1::2])/2

How to convert a binary matrix to a bipolar one in python

There is a function in Keras to generate a binary matrix for an array of labels:
# Consider an array of 5 labels out of a set of 3 classes {0, 1, 2}:
> labels
array([0, 2, 1, 2, 0])
# `to_categorical` converts this into a matrix with as many
# columns as there are classes. The number of rows
# stays the same.
> to_categorical(labels)
array([[ 1., 0., 0.],
[ 0., 0., 1.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 1., 0., 0.]], dtype=float32)
I need the above functionality, but having -1 instead of zeros. I didn't find any option or other functions to do it. Is there any easy way to do that?
You could do the following:
import numpy as np
arr = np.array([[1., 0., 0.],
[0., 0., 1.],
[0., 1., 0.],
[0., 0., 1.],
[1., 0., 0.]])
arr[np.isclose(arr, 0)] = -1
print(arr)
Output
[[ 1. -1. -1.]
[-1. -1. 1.]
[-1. 1. -1.]
[-1. -1. 1.]
[ 1. -1. -1.]]
Just rescale your data:
2*to_categorical(labels)-1

Do the "AND" operation with the first column and the second list in the matrix

My array is:
[[1. 1. 0. 0. 1.]
[0. 1. 0. 1. 0.]
[0. 1. 1. 0. 0.]
[1. 1. 0. 1. 0.]
[1. 0. 1. 0. 0.]
[0. 1. 1. 0. 0.]
[1. 0. 1. 0. 0.]
[1. 1. 1. 0. 1.]
[1. 1. 1. 0. 0.]
[6. 7. 6. 2. 2.]]
The last line is the sum of the columns.
I want to do the "AND" operation with the zero column and the first column in the matrix.
I use Program language is Python3.5.
I take the zero column and the first column.
[[1. 1.] 1
[0. 1.] 0
[0. 1.] 0
[1. 1.] 1
[1. 0.] 0
[0. 1.] 0
[1. 0.] 0
[1. 1.] 1
[1. 1.] 1
[6. 7.]]
And count the results and save them in the list.
How can I do?
I'm not sure that I understand the question but maybe something like this:
arr = [[1., 1.], [0., 1.], [0., 1.], [1., 1.], [1., 0.], [0., 1.], [1., 0.], [1., 1.], [1., 1.], [6., 7.]]
for a in arr:
if (a[0] and a[1]):
print(1)
else:
print(0)
I assume that you are using numpy. Then you can simply take the slice of the array and apply the function numpy.all to this slice, which concatenates all elements in one big AND-operation. You have to configure the function to perform the operation along the desired axis with the particular argument axis.
CODE
from __future__ import print_function
import numpy as np
a = np.array([[1., 1., 0., 0., 1.],
[0., 1., 0., 1., 0.],
[0., 1., 1., 0., 0.],
[1., 1., 0., 1., 0.],
[1., 0., 1., 0., 0.],
[0., 1., 1., 0., 0.],
[1., 0., 1., 0., 0.],
[1., 1., 1., 0., 1.],
[1., 1., 1., 0., 0.],
[6., 7., 6., 2., 2.]])
slice_a = a[0:-1, 0:2] # Do the slicing, "0:-1" zeroth row to the second last row,
# "0:2" zeroth to the first column
and_slice = np.all(slice_a, axis=1) # Perform the boolean operation
print( slice_a )
print( and_a )
OUTPUT
array([[1., 1.],
[0., 1.],
[0., 1.],
[1., 1.],
[1., 0.],
[0., 1.],
[1., 0.],
[1., 1.],
[1., 1.]])
array([ True, False, False, True, False, False, False, True, True])
BONUS
If you want the output to be a column vector add the argument keepdims=True:
and_slice = np.all(slice_a, axis=1, keepdims=True)
If arr has type list you can try:
arr = [[1., 1.], [0., 1.], [0., 1.], [1., 1.], [1., 0.], [0., 1.], [1., 0.], [1., 1.], [1., 1.], [6., 7.]]
result = [int(row[0] and row[1]) for row in arr[:-1]]
print(result)
Output
[1, 0, 0, 1, 0, 0, 0, 1, 1]
Try this:
for s in list:
s.append(int(s[0]) & int(s[1]))
or
anded = [int(s[0]) & int(s[1]) for s in list]
print(sum(anded))
All this code does is iterate over your list, and take the elements from position 0 and 1 from the sub-list, convert them to integers (looks like they were doubles before), bitwise and them and append the result to the sub-list. At the end when you get your sums, you can just use the same operation as with the result of the columns.

How to calculate percentile of score along z axis of 3d array?

I'm trying to calculate percentiles using scipy.stats.percentileofscore() along the z axis of a 3d numpy array, with the scores in a 2d array.
For example, my 3d array might look like this:
data = array([[[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]],
[[ 2., 2., 2.],
[ 2., 2., 2.],
[ 2., 2., 2.]],
[[ 3., 3., 3.],
[ 3., 3., 3.],
[ 3., 3., 3.]]])
And the scores to calculate percentiles for might look like this:
scores = array([[ 1., 1., 2.],
[ 1., 1., 2.],
[ 1., 1., 2.]])
I want to apply percentileofscore() at each location (m,n) in this way:
percentileofscore(data[:,m,n], scores[m,n])
The result would be this:
array([[ 33.33, 33.33, 66.66],
[ 33.33, 33.33, 66.66],
[ 33.33, 33.33, 66.66]])
I can do this with nested loops, but am applying this to large arrays so would like a more optimized approach. I'm having a hard time wrapping my head around how to accomplish this.
You can avoid a nested loop by reshaping your array. I think in order to avoid loops completely you will have to write a custom percentile function.
import numpy as np
from scipy.stats import percentileofscore
x = 3
y = 3
z = 3
d = a.reshape(z, x*y)
scores_d = scores.reshape(x*y,1)
percentiles_d = [percentileofscore(d[:, i], scores_d[i]) for i in range(x*y)]
percentiles_d = np.round(np.array(percentiles_d), 2).reshape(x,y)
print(percentiles_d)
[[ 33.33 33.33 66.67]
[ 33.33 33.33 66.67]
[ 33.33 33.33 66.67]]

Python - Average values of numpy multidimensionnal array every specific time

I have a multidimensionnal array "test[:,:,:]" and i would like to get averaged values on the test.shape[0] dimension for every 4 "frames" i would like to keep the same dimensions of my array and substitute the 4 values by the mean value.
As example:
test=np.array([[[ 2., 1., 1.],
[ 1., 1., 1.]],
[[ 3., 1., 1.],
[ 1., 1., 1.]],
[[ 3., 1., 1.],
[ 1., 1., 1.]],
[[ 5., 1., 1.],
[ 1., 1., 1.]],
[[ 2., 1., 1.],
[ 1., 1., 1.]],
[[ 3., 1., 1.],
[ 1., 1., 1.]],
[[ 3., 1., 1.],
[ 1., 1., 1.]],
[[ 5., 1., 1.],
[ 1., 1., 1.]],
[[ 2., 1., 1.],
[ 1., 1., 1.]]])
for i in range(test.shape[0]-1,4):
test_mean = (test[i,:,:]+test[i+1,:,:]+test[i+2,:,:]+test[i+3,:,:])/4.
But, i don't keep the same dimension...what is the best way to do that?
You are overwriting test_mean every time. A good start is:
test_mean = np.zeros_like(test)
for i in xrange(test.shape[0]-4):
test_mean[i] = test[i:i+4].mean(axis=0)
Here is a more efficient implementation from scipy:
from scipy.ndimage import uniform_filter1d
test_mean2 = uniform_filter1d(test, 4, axis=0)
Check the documentation to understand how the result is stored and what options you have to treat boundary values.

Categories