Accessing second index in 3-d numpy array - python

I have a 2-d numpy array that I convert into a 3-d array by using:
trainSet = numpy.reshape(trainSet, (trainSet.shape[0], 1, trainSet.shape[1]))
My problem is I'm trying to adjust values in the 1st axis (the new one). However, no matter what I try I can not actually figure out how to access the 1's in the new axis. I've tried a multitude of print statements such as
print(trainSet[0][0][0])
print(trainSet[1][0][1])
but no matter what I try I can not print out any 1's, just the contents of the 2-d array. I know it's a 3d array because when I use
print(trainSet.shape)
I get
(12, 1, 793)
Any help would be immensely appreciated!

The one refers to the size of that particular dimension, not the content of the array. The array [[5 5]] has shape (1, 2) but, still, you don't really expect its values must include 1 for that reason, do you?
What inserting a dimension of length one does is increasing the nesting level by one, so a 2d array [[a b] [c d]] will become [[[a b] [c d]]] or [[[a b]] [[c d]]] or [[[a] [b]] [[c] [d]]] depending on where you insert the new axis.
In particular, there are no new elements.

If I didn't mistake your question, what you want is
trainSet[:,0,:]

the amount of values remains the same, you're just creating a 3D structure instead of the 2D structure.

Related

Numpy: trouble obtaining a 2D slice of 3D array

Similar questions have been asked on SO, but never in the form that I needed.
I seem to be having trouble understanding NumPy slicing behavior.
Lets say I have an Numpy Array of shape 512x512x120
vol1=some_numpy_array
print(x.shape) #result: (512,512,120)
I want to take a "z-slice" of this array, however I end up with a 512x120 array instead of a 512x512 one
I try the following code for instance
zSlice=(vol1[:][:][2]).squeeze()
print(zSlice.shape()) #result: (512,120)
Why is the resulting array shape (512,120) and not (512,512)? How can I fix this problem?
You have to slice at once:
vol1[:, :, 2].squeeze()
>>> vol1[:, :, 2].squeeze().shape
(512, 512)
Because doing [:] repeatedly doesn't do anything:
>>> (vol1[:][:] == vol1).all()
True
>>>
It's because [:] gets the whole of the list... doing it multiple times does not change anything.
The problem with vol1[:][:][2] is:
vol1[:] will give the entire array, then again [:] gives the entire array, and finally [2] gives the array at index 2 to in the outer axis, eventually vol1[:][:][2] is nothing but vol1[2] which is not what you want.
You need to take numpy array slice:
vol1[:, :, 2].
Now, it will take all the items from outermost, and outer axes, but only item at index 2 for the inner most axis.

Numpy-like slicing in Julia

In Python/Numpy I can slice arrays in this form:
arr = np.ones((3,4,5))
arr[2]
and the shape will be maintained:
(arr[2]).shape # prints (4, 5)
Which means that, if I want to keep the shape of the array, the following code works for N-dimensional arrays
arr = np.ones((3,4,5,2,2))
(arr[2]).shape # prints (4, 5, 2, 2)
This is great if I want to write functions that work for N-dim arrays preserving their output.
In Julia, however, the same action does not preserve the structure:
arr = ones(3,4,5)
size(arr[3]) # prints () (0-dimensinoal)
size(arr[3,:]) # prints (20,)
because of partial linear indexing. So if want to keep the original dimensions I need to write arr[3,:,:], which only works for 3D arrays. If I want a 4D array I would have to use arr[3,:,:,:] and so on. The code isn't general.
Furthermore, when you get to array that are 5 dimensions or more (which is the case I'm working with now) this notation gets extremely cumbersome.
Is there any way I can write code like I do in Python and make it general? I couldn't even think of a nice clean way with reshape, let alone a way that's as clean as Python.
Notice that in Python the shape is only preserved if you slice the first dimension of the array. In Julia you can use slicedim(A, d, i) to slice dimension d of array A at index i.

Python: Creating multi dimensional array of multidimensional zero array

Hello I have the following question. I create zero arrays of dimension (40,30,80). Now I need 7*7*7 of these zero arrays in an array. How can I do this?
One of my matrices is created like this:
import numpy as np
zeroMatrix = np.zeros((40,30,80))
My first method was to put the zero matrices in a 7*7*7 list. But i want to have it all in a numpy array. I know that there is a way with structured arrays I think, but i dont know how. If i copy my 7*7*7 list with np.copy() it creates a numpy array with the given shape, but there must be a way to do this instantly, isnt there?
EDIT
Maybe I have to make my question clearer. I have a 7*7 list of my zero matrices. In a for loop all of that arrays will be modified. In another step, this tempory list is appended to an empty list which will have a length of 7 in the end ( So i append the 7*7 list 7 times to the empty list. In the end I have a 7*7*7 List of those matrices. But I think this will be better If I have a numpy array of these zero matrices from the beginning.
Building an array of same-shaped arrays is not well supported by numpy which prefers to create a maximum depth array of minimum depth elements instead.
It turns out that numpy.frompyfunc is quite useful in circumventing this tendency where it is unwanted.
In your specific case one could do:
result = np.frompyfunc(zeroMatrix.copy, 0, 1)(np.empty((7, 7, 7), object))
Indeed:
>>> result.shape
(7, 7, 7)
>>> result.dtype
dtype('O')
>>> result[0, 0, 0].shape
(40, 30, 80)

How to declare a 2 dimensional array with different row lengths using np.array?

For example, I want a 2 row matrix, with a first row of length 1, and second row of length 2. I could do,
list1 = np.array([1])
list2 = np.array([2,3])
matrix = []
matrix.append(list1)
matrix.append(list2)
matrix = np.array(matrix)
I wonder if I could declare a matrix of this shape directly in the beginning of a program without going through the above procedure?
A matrix is by definition a rectangular array of numbers. NumPy does not support arrays that do not have a rectangular shape. Currently, what your code produces is an array, containing a list (matrix), containing two more arrays.
array([array([1]), array([2, 3])], dtype=object)
I don't really see what the purpose of this shape could be, and would advise you simply use nested lists for whatever you are doing with this shape. Should you have found some use for this structure with NumPy however, you can produce it much more idiomatically like this:
>>> np.array([list1,list2])
array([array([1]), array([2, 3])], dtype=object)

same numbers but different shape when slicing 2 dimensional arrays in python with numpy

I'm messing around with 2-dimensional slicing and don't understand why leaving out some defaults grabs the same values from the original array but produces different output. What's going on with the double brackets and shape changing?
x = np.arange(9).reshape(3,3)
y = x[2]
z = x[2:,:]
print y
print z
print shape(y)
print shape(z)
[6 7 8]
[[6 7 8]]
(3L,)
(1L, 3L)
x is a two dimensional array, an instance of NumPy's ndarray object. You can index/slice these objects in essentially two ways: basic and advanced.
y[2] fetches the row at index 2 of the array, returning the array [6 7 8]. You're doing basic slicing because you've specified only an integer. You can also specify a tuple of slice objects and integers for basic slicing, e.g. x[:,2] to select the right-hand column.
With basic slicing, you're also reducing the number of dimensions of the returned object (in this case from two to just one):
An integer, i, returns the same values as i:i+1 except the dimensionality of the returned object is reduced by 1.
So when you ask for the shape of y, this is why you only get back one dimension (from your two-dimensional x).
Advanced slicing occurs when you specify an ndarray: or a tuple with at least one sequence object or ndarray. This is the case with x[2:,:] since 2: counts as a sequence object.
You get back an ndarray. When you ask for its shape, you will get back all of the dimensions (in this case two):
The shape of the output (or the needed shape of the object to be used for setting) is the broadcasted shape.
In a nutshell, as soon as you start slicing along any dimension of your array with :, you're doing advanced slicing and not basic slicing.
One brief point worth mentioning: basic slicing returns a view onto the original array (changes made to y will be reflected in x). Advanced slicing returns a brand new copy of the array.
You can read about array indexing and slicing in much more detail here.

Categories

Resources