NumPy arrays iterate over the left-most axis first. Thus if B has shape
(2,3,4), then B[0] has shape (3,4) and B[1] has shape (3,4). In this sense,
you could think of B as 2 arrays of shape (3,4). You can sort of see the two
arrays in the repr of B:
In [233]: B = np.arange(2*3*4).reshape((2,3,4))
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7], <-- first (3,4) array
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19], <-- second (3,4) array
[20, 21, 22, 23]]])
You can also think of B as containing four 2x3 arrays by iterating over the last index first:
for i in range(4):
print(B[:,:,i])
# [[ 0 4 8]
# [12 16 20]]
# [[ 1 5 9]
# [13 17 21]]
# [[ 2 6 10]
# [14 18 22]]
# [[ 3 7 11]
# [15 19 23]]
but you could just as easily think of B as three 2x4 arrays:
for i in range(3):
print(B[:,i,:])
# [[ 0 1 2 3]
# [12 13 14 15]]
# [[ 4 5 6 7]
# [16 17 18 19]]
# [[ 8 9 10 11]
# [20 21 22 23]]
NumPy arrays are completely flexible this way. But as far as the repr of B is concerned, what you see corresponds to two (3x4) arrays since B iterates over the left-most axis first.
for arr in B:
print(arr)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]
Answer from unutbu on Stack OverflowNumPy arrays iterate over the left-most axis first. Thus if B has shape
(2,3,4), then B[0] has shape (3,4) and B[1] has shape (3,4). In this sense,
you could think of B as 2 arrays of shape (3,4). You can sort of see the two
arrays in the repr of B:
In [233]: B = np.arange(2*3*4).reshape((2,3,4))
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7], <-- first (3,4) array
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19], <-- second (3,4) array
[20, 21, 22, 23]]])
You can also think of B as containing four 2x3 arrays by iterating over the last index first:
for i in range(4):
print(B[:,:,i])
# [[ 0 4 8]
# [12 16 20]]
# [[ 1 5 9]
# [13 17 21]]
# [[ 2 6 10]
# [14 18 22]]
# [[ 3 7 11]
# [15 19 23]]
but you could just as easily think of B as three 2x4 arrays:
for i in range(3):
print(B[:,i,:])
# [[ 0 1 2 3]
# [12 13 14 15]]
# [[ 4 5 6 7]
# [16 17 18 19]]
# [[ 8 9 10 11]
# [20 21 22 23]]
NumPy arrays are completely flexible this way. But as far as the repr of B is concerned, what you see corresponds to two (3x4) arrays since B iterates over the left-most axis first.
for arr in B:
print(arr)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]
I hope the below example would clarify the second part of your question where you have asked about getting a 2X3 matrics when you type print(B[:,:,1])
import numpy as np
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]]]
B = np.array(B)
print(B)
print()
print(B[:,:,1])
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]]
[[ 2 6 10]
[14 18 22]]
Since the dimension of B is 2X3X4, It means you have two matrices of size 3X4 as far as repr of B is concerned
Now in B[:,:,1] we are passing : , : and 1. First : indicates that we are selecting both the 3X4 matrices. The second : indicates that we are selecting all the rows from both the 3X4 matrices. The third parameter 1 indicates that we are selecting only the second column values of all the rows from both the 3X4 matrices. Hence we get
[[ 2 6 10]
[14 18 22]]
Hi, guys!
I have a three dimensional array x=np.random.randn(10, 5, 5)
When I use: x2 = x[:, [1, 2], [1, 2]] I should get an array of size [10, 2, 2] but I don't. Instead I get an array of shape [10, 2].
To get what I want, I have to use two lines of code: x2 = x[:, [1, 2], :]; x2=x2[:, :, [1, 2]].
I don't understand why is numpy behaving in this manner. Any explanation is much appreciated
Thank you!
arr = np.array([[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]])
# array([[[ 1, 2, 3],
# [ 4, 5, 6]],
# [[ 7, 8, 9],
# [10, 11, 12]]])
arr.shape # ------> (2,2,3)
# Think of them as axis
# lets create the first 2 axis of (`2`, ...)
# |(1)
# |
# |
# |
# |---------(0)
# now lets create second 2 axis of (2, `2`, ..)
# (1,1)
# |
# |---(1,0)
# |
# |
# |
# | |(0,1)
# |---------|---(0,0)
# now lets create the last 3 axis of (2, 2, `3`)
# /``(1,1,0) = 10
# |-- (1,1,1) = 11
# | \__(1,1,2) = 12
# |
# | /``(1,0,0) = 7
# |--|--(1,0,1) = 8
# | \__(1,0,2) = 9
# |
# |
# | /``(0,1,0) = 4
# | |--(0,1,1) = 5
# | \__(0,1,2) = 6
# | |
# | |
# |---------|---/``(0,0,0) = 1
# |--(0,0,1) = 2
# \__(0,0,2) = 3
# now suppose you ask
arr[0, :, :] # give me the first axis alon with all it's component
# |
# | /``(0,1,0) = 4
# | |--(0,1,1) = 5
# | \__(0,1,2) = 6
# | |
# | |
# |---------|---/``(0,0,0) = 1
# |--(0,0,1) = 2
# \__(0,0,2) = 3
# So it will print
# array([[1, 2, 3],
# [4, 5, 6]])
arr[:, 0, :] # you ask take all the first axis 1ut give me only the first axis of the first axis and all its components
#
#
#
#
# | /``(1,0,0) = 7
# |--|--(1,0,1) = 8
# | \__(1,0,2) = 9
# |
# |
# |
# |
# |
# |
# |
# |---------|---/``(0,0,0) = 1
# |--(0,0,1) = 2
# \__(0,0,2) = 3
# so you get the output
# array([[1, 2, 3],
# [7, 8, 9]])
# like wise you ask
print(arr[0:2, : , 2])
# so you are saying give (0,1) first axis, all of its children and only 3rd (index starts at 0 so 2 means 3) children
# 0:2 means 0 to 2 `excluding` 2; 0:5 means 0,1,2,3,4
#
# |
# | \__(1,1,2) = 12
# |
# |
# |--
# | \__(1,0,2) = 9
# |
# |
# |
# |
# | \__(0,1,2) = 6
# | |
# | |
# |---------|---/
# |
# \__(0,0,2) = 3
# so you get
# array([[ 3, 6],
# [ 9, 12]])
Going In
Given the array:
arr = np.array([[[1,2,3], [4,5,6]], [[7,8,9],[10,11,12]]])
The shape of arr, given by arr.shape is (2,2,3).
That basically means that if we start from outside (and ignore the first square bracket), we have 2 arrays in that scope. If we enter to one of those we can count 2 arrays and if we enter either we find 3 elements. I think having this view is quite helpful in understanding the following.
Specifying arr[1,1,2] selects the second array(index 1) in the outermost scope, and then selects the second array in the following scope and then selects the third element. The output is a single number:
12
specifying arr[:,1,2] first simultaneously selects all arrays at the outermost scope and then for each of these selects the second array (index 1). When we then enter into the next scope, we pick out the 3rd elements. This outputs two numbers:
array([ 6, 12])
specifying arr[:, : , 2] outputs 4 numbers since 1. at the first scope we selected all arrays (2) 2. at the next scope we selected all array (2 for each in the first)
array([[ 3, 6],
[ 9, 12]])
Coming out
Instinctually, the reason why they appear as 2x2 array can be viewed as receding from the lowermost scope. Elements are getting enclosed in square brackets because that share a scope. 3 and 6 will be in one array while 9 and 12 will be in another array.
Consider the following:
A = np.zeros((2,3)) print(A) [[ 0. 0. 0.] [ 0. 0. 0.]]
This make sense to me. I'm telling numpy to make a 2x3 matrix, and that's what I get.
However, the following:
B = np.zeros((2, 3, 4)) print(B)
Gives me this:
[[[ 0. 0. 0. 0.] [ 0. 0. 0. 0.] [ 0. 0. 0. 0.]] [[ 0. 0. 0. 0.] [ 0. 0. 0. 0.] [ 0. 0. 0. 0.]]]
This doesn't make sense to me. Aren't I telling numpy to make a cube which has 4 2x3 matrices? I'm even more confused because although the data structure looks incorrect, the slicing works exactly as planned:
print(B[:,:,1]) [[ 0. 0. 0.] [ 0. 0. 0.]]
I'm missing something about how these arrays are constructed, but I'm not sure what. Can someone explain what I'm missing or not understanding?
Thanks so much!
I think you're just getting hung up on how this array is being printed out. You can't really represent the 3D array properly on screen, so numpy has chosen the convention of putting the last dimension of the array in the columns, the second-to-last in sub-array rows, and earlier dimensions in sub-array groupings.
So to get something that prints the way you expect (I'm guessing about your expectations), you could write:
A = np.zeros((4, 2, 3))
print(A)
[[[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]]]
But this doesn't behave the way you describe above because you would index into the first axis to get a 2x3 array out
print A[1]
[[ 0. 0. 0.]
[ 0. 0. 0.]]
Look at it this way: the first dimension is what you use when treating the array like a list:
>>> zs = zeros((2, 3, 4))
>>> for subarray in zs:
... print(subarray.shape)
(3, 4)
(3, 4)
>>> len(zs)
2
>>> zs[0].shape # this is a 2d array!
(3, 4)
>>> len(zs[0])
3
>>> len(zs[0, 0])
4
The first dimension of a 2d array is commonly called rows.