How to rearrange a 3d numpy array? - python

I have a numpy ndarray, something like this (my array is much bigger, I am only giving this in order to explain what I need to do):
a = [[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]]
[[ 9 10 11]
[12 13 14]
[15 16 17]]
[[18 19 20]
[21 22 23]
[24 25 26]]]
I am looking for an elegant way to rearrange the array in order to get something like this:
a_new=[[[ 0 9 18]
[ 1 10 19]
[ 2 11 20]]
[[ 3 12 21]
[ 4 13 22]
[ 5 14 23]]
[[ 6 15 24]
[ 7 16 25]
[ 8 17 26]]]

Simply permute axes -
a.transpose(1,2,0)
# or np.moveaxis(a,0,2)

Related

more efficient way to cut through 3D matrix along all the plains in numpy

I am trying to cut a 3D array along all it's plains. To capture 2D arrays along all the axes of the 3D array, this will create 13 2D arrays. I was wondering if there is a way to do this with axis and rotations? This will create 3 vertical and 3 horizontal slices front to back and 3 vertical left to right and 4 diagonal.
import numpy as np
r = np.array([
[[1,2,3],
[4,5,6],
[2,8,9]],
[[10,11,12],
[13,14,15],
[2,17,18]],
[[19,20,21],
[22,23,24],
[25,26,27]],
])
a = np.vstack([r[0,:,0],r[1,:,0],r[2,:,0]])
b = np.vstack([r[0,:,1],r[1,:,1],r[2,:,1]])
c = np.vstack([r[0,:,2],r[1,:,2],r[2,:,2]])
d = np.vstack([r[0,0,:],r[1,0,:],r[2,0,:]])
e = np.vstack([r[0,1,:],r[1,1,:],r[2,1,:]])
f = np.vstack([r[0,2,:],r[1,2,:],r[2,2,:]])
g = r[0]
h = r[1]
i = r[2]
j = np.vstack([r[0,:,0],r[1,:,1],r[2,:,2]])
k = np.vstack([r[0,:,2],r[1,:,1],r[2,:,0]])
l = np.vstack([r[0,2,:],r[1,1,:],r[2,0,:]])
m = np.vstack([r[0,0,:],r[1,1,:],r[2,2,:]])
al= np.array([a,b,c,d,e,f,g,h,i,j,k,l,m])
print(al,end='\n')
# output
[[[ 1 4 2] #a
[10 13 2]
[19 22 25]]
[[ 2 5 8] #b
[11 14 17]
[20 23 26]]
[[ 3 6 9] #c
[12 15 18]
[21 24 27]]
[[ 1 2 3] #d
[10 11 12]
[19 20 21]]
[[ 4 5 6] #e
[13 14 15]
[22 23 24]]
[[ 2 8 9] #f
[ 2 17 18]
[25 26 27]]
[[ 1 2 3] #g
[ 4 5 6]
[ 2 8 9]]
[[10 11 12] #h
[13 14 15]
[ 2 17 18]]
[[19 20 21] #i
[22 23 24]
[25 26 27]]
[[ 1 4 2] #j
[11 14 17]
[21 24 27]]
[[ 3 6 9] #k
[11 14 17]
[19 22 25]]
[[ 2 8 9] #l
[13 14 15]
[19 20 21]]
[[ 1 2 3] #m
[13 14 15]
[25 26 27]]]

Change values in np array Python

I am trying to change the value in np array if there is a match
For example, a np array a and its shape is (50,4)
a.shape#(50,4)
I need to check if the np array a has this value [0,1,20,4] in the 1st axis, then I need to change that into [-1,-1,-1,-1].
I tried this format -
a[a==[0,1,20,4]]=[-1,-1,-1,-1]
But, this is not working,
How to do this modification?
This solves it for random array of shape (50,4)
b = np.random.randint(5,size=(50,4))
c = np.equal(b,[4,1,2,3])
ai = np.array(c.all(axis=1).nonzero())
np.put_along_axis(b,ai,[-1,-1,-1,-1],axis=0)
change [4,1,2,3] to [0,1,20,4]
Maybe try doing row-wise comparison with np.tile and np.argwhere like this:
import numpy as np
# Create dummy data
x = np.random.randint(29, size=(49, 4))
x = np.concatenate([[[0,1,20,4]], x])
print('Before --> \n', x)
# Compare row-wise
x[np.argwhere(np.all(x==np.reshape(np.tile([0,1,20,4], reps=x.shape[0]), x.shape),axis=1))] = [-1,-1,-1,-1]
print('After --> \n', x)
Before -->
[[ 0 1 20 4]
[ 1 17 5 2]
[19 8 24 17]
[ 1 23 16 3]
[ 0 15 0 20]
[14 23 9 23]
[ 1 27 5 27]
[15 24 24 17]
[ 2 28 8 4]
[26 26 6 10]
[18 13 5 28]
[10 25 18 15]
[ 6 17 8 2]
[ 4 26 26 15]
[18 16 18 24]
[ 0 11 15 22]
[20 27 0 0]
[ 9 22 16 2]
[22 11 8 23]
[21 10 6 23]
[14 16 0 10]
[14 27 22 9]
[ 4 0 10 15]
[12 0 28 25]
[ 8 28 9 28]
[12 3 26 24]
[23 3 26 25]
[ 0 6 16 4]
[ 1 20 1 19]
[11 5 9 11]
[20 15 18 5]
[25 0 17 27]
[20 24 3 19]
[13 12 17 4]
[ 1 13 25 22]
[27 10 11 18]
[ 4 5 12 8]
[11 19 17 15]
[26 7 3 10]
[21 14 27 21]
[26 12 8 13]
[27 8 1 17]
[20 28 0 20]
[ 1 12 11 16]
[ 4 0 3 22]
[11 12 3 8]
[15 24 3 8]
[ 4 23 17 20]
[21 1 23 12]
[ 0 27 3 22]
[15 5 17 28]]
After -->
[[-1 -1 -1 -1]
[ 1 17 5 2]
[19 8 24 17]
[ 1 23 16 3]
[ 0 15 0 20]
[14 23 9 23]
[ 1 27 5 27]
[15 24 24 17]
[ 2 28 8 4]
[26 26 6 10]
[18 13 5 28]
[10 25 18 15]
[ 6 17 8 2]
[ 4 26 26 15]
[18 16 18 24]
[ 0 11 15 22]
[20 27 0 0]
[ 9 22 16 2]
[22 11 8 23]
[21 10 6 23]
[14 16 0 10]
[14 27 22 9]
[ 4 0 10 15]
[12 0 28 25]
[ 8 28 9 28]
[12 3 26 24]
[23 3 26 25]
[ 0 6 16 4]
[ 1 20 1 19]
[11 5 9 11]
[20 15 18 5]
[25 0 17 27]
[20 24 3 19]
[13 12 17 4]
[ 1 13 25 22]
[27 10 11 18]
[ 4 5 12 8]
[11 19 17 15]
[26 7 3 10]
[21 14 27 21]
[26 12 8 13]
[27 8 1 17]
[20 28 0 20]
[ 1 12 11 16]
[ 4 0 3 22]
[11 12 3 8]
[15 24 3 8]
[ 4 23 17 20]
[21 1 23 12]
[ 0 27 3 22]
[15 5 17 28]]
For example for a random matrix
x = np.random.randint(1,11,size=(10,4))
>> array([[10, 1, 7, 7],
[ 3, 1, 3, 2],
[ 8, 10, 2, 9],
[ 4, 6, 4, 4],
[ 1, 4, 3, 5],
[10, 1, 5, 4],
[ 7, 10, 8, 8],
[ 5, 10, 8, 3],
[ 6, 5, 5, 3],
[ 7, 2, 5, 7]])
Check all rows that are equal to target row
rows_cond = np.all(x == [1,4,3,5], axis=1)
this returns a boolean array that can be used to modify the desired rows
x[rows_cond,:] = [-1,-1,-1,-1]

Numpy.reshape for multidimensional Numpy arrays gives same size but different order of numbers

I want to convert an array of shape (a, b, c, d) into a shape (b*c*d, a).
The problem is the output of Array A and B is different:
x = np.array([np.arange(1,37)]) #1D array of 1 to 36.
a = 3
b = 2
c = 2
d = 3
Array = np.reshape(x, (a, b, c, d)) #shape (3, 2, 2, 3)
A = poop.reshape(a, b*c*d).T
B = poop.reshape(b*c*d, a)
print("Array shape:" + str(Array.shape))
print(Array)
print("#####")
print("Array A:")
print(A)
print("#####")
print("Array B:")
print(B)
I would of thought that Numpy's reshape takes (row, column) as input, so reversing then transposing would lead to the same result (column, row).T.
Changing the "Order" parameter does not seem to make array B match array A.
Thank you.
The output is:
Array shape:(3, 2, 2, 3)
[[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
[[[13 14 15]
[16 17 18]]
[[19 20 21]
[22 23 24]]]
[[[25 26 27]
[28 29 30]]
[[31 32 33]
[34 35 36]]]]
#####
Array A:
[[ 1 13 25]
[ 2 14 26]
[ 3 15 27]
[ 4 16 28]
[ 5 17 29]
[ 6 18 30]
[ 7 19 31]
[ 8 20 32]
[ 9 21 33]
[10 22 34]
[11 23 35]
[12 24 36]]
#####
Array B:
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]
[13 14 15]
[16 17 18]
[19 20 21]
[22 23 24]
[25 26 27]
[28 29 30]
[31 32 33]
[34 35 36]]

Accessing np.array elements depending on another np.array in python

I have a numpy.ndarray (arr), which contains multiple 3x4 arrays. In the other hand I have a 1xN referenceArray, which shows, which subarray should I take out from the arr.
arr= [[1 2 3]
[4 5 6]
[7 8 9]
[10 11 12]]
[[13 14 15]
[16 17 18]
[19 20 21]
[22 23 24]]
[[25 26 27]
[28 29 30]
[31 32 33]
[34 35 36]]
.
.
.
referenceArray = [0 1 4 8 9]
E.g.
arr[0]gives me the subarray from arr
arr:[[1 2 3]
[4 5 6]
[7 8 9]
[10 11 12]]
and arr[1]
arr:[[13 14 15]
[16 17 18]
[19 20 21]
[22 23 24]]
My problem is, the elements and also the size of the referenceArray is changes dynamically. So, how can I access only those subarrays from arr, which depends on the written elements in referenceArray and append those in a new array?

How can I add small 2D array to larger array?

I have a larger 2D array, and I would like to add a smaller 2D array.
from numpy import *
x = range(25)
x = reshape(x,(5,5))
print x
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
y = [66,66,66,66]
y = reshape(y,(2,2))
print y
[[66 66]
[66 66]]
I would like to add the values from array y to x starting at 1,1 so that x looks like this:
[[ 0 1 2 3 4]
[ 5 72 73 8 9]
[10 77 78 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
Is this possible with slicing? Can someone please suggest the correct formatting of the slice statement to achieve this?
Thanks
Yes, you can use slicing on numpy arrays:
In [20]: x[1:3,1:3] += y
In [21]: print x
[[ 0 1 2 3 4]
[ 5 72 73 8 9]
[10 77 78 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
x[1:3, 1:3] += y
Add y in-place to the slice of x you want to modify. Note that numpy indexing counts from 0, not 1. Also, note that for this particular choice of y,
x[1:3, 1:3] += 66
will achieve the same effect in a simpler manner.

Categories