Suppose there is an array
(1) x=np.array([[1,2],[1,2],[1,2]])
and a second array
(2) y=np.array([[1],[1,2],[1,2,3]])
The command size(x) returns the total count of all elements along every axis. In this case 6. However, size(y) returns 3. This must be because numpy interprets (2) in this case as three elements (the three subarrays) along one axis, although shape(y) returns (3, ). My question is now: how can I get numpy to interpret (2) as an array with three axes, so that size(y) returns the total count of all atomic elemets, which is 6?
I don't think it's possible to get the number of elements from y without looping over the objects.
The problem is that the elements of y are not numbers, they are objects (lists). Numpy does not support lists of lists and therefore it stores it as a 1-dimensional array of objects. I don't think there are Numpy methods to get the total number of elements in y.
Related
This question already has an answer here:
why there is deference between the output type of this two Numpy slice commands
(1 answer)
Closed last year.
I'm a little bit new to Python & Numpy, but I've noticed that when you call operator [] on a numpy array A, if it's a single index that is used (e.g., A[1]), the resulting sub-array is 1 dimension smaller, but if it's a range of indices (e.g., A[1:]) the dimension of the subarray remains unchanged, even if the range of indices covers only a single index, e.g., in this above case, if A was 2x2, A[1:] is effectively just a single index, but the resulting size is not the same as A[1].
My question is: is this always true in that if you supply a range of indices when extracting a subarray, the dimension doesn't change, and that a single index always reduces the dimension by 1? Are there edge cases?
That is always the case. When you use one index-value, e.g. A[1], you are effectively saying "give me the subarray A[1]", which, by definition, has a dimensionality smaller (by 1).
When you request a range of indices, e.g., A[1:] you are "cropping" A, to get everything but the first slice (A[0]). See, the range of indices define the axis you "lost" in the previous case (A[1]).
The following docs should be helpful to understand numpy arrays (indexing):
Arrays: https://numpy.org/doc/stable/user/absolute_beginners.html#more-information-about-arrays
Indexing: https://numpy.org/doc/stable/user/basics.indexing.html
Suppose I have multiple NxN 2D arrays stored into a list in Python 3. I want to collapse all the arrays into 1 array, with the same dimensions NxN, but such that each element of this new array contains a 1xN array of the corresponding values from the original arrays.
To give you some more context, each array in this list corresponds to the set of values at a given time. For each new time point, I am storing the updated version of that array into the list. Once that's done, I want to compute the standard deviation of the values at each (i,j) element in the array.
I tried using a for loop, but it takes far too long for my simulations because this is a set of 100,000 arrays. I was wondering if there were any numpy or vectorized functions that can help me perform this operation more efficiently. Thanks!
Lets say l is your list of arrays. You need to get std of corresponding elements of those arrays into a single array:
std_l = np.std(np.stack(l),axis=0)
I have two numpy arrays, one bigger than another, but both with the same number of dimensions.
I want to get a slice from the bigger array that matches the size of the smaller array. (Starting from 0,0,0....)
So, imagine the big array has shape (10,5,7).
And the small array has shape (10,4,6).
I want to get from the bigger array this slice:
biggerArray[:10,:4,:6]
The length of the shape tuple may vary, and I want to do it for any number of dimensions (Both will always have the same number of dimensions).
How to do that? Is there a way to use tuples as ranges in slices?
Construct the tuple of slice objects manually. biggerArray[:10, :4, :6] is syntactic sugar for biggerArray[(slice(10), slice(4), slice(6))], so:
biggerArray[tuple(map(slice, smallerArray.shape))]
or
biggerArray[tuple(slice(0, n) for n in smallerArray.shape)]
You may want to assert result.shape == smallerArray.shape afterwards, just in case the input shapes weren't what you thought they were.
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.
I am trying to work with lists of numpy matrices and am encountering an annoying problem.
Let's say I start with a list of ten 2x2 zero matrices
para=[numpy.matrix(numpy.zeros((2,2)))]*(10)
I access individual matrices like this
para[0]
para[1]
and so on. So far so good.
Now, I want to modify the first row of the second matrix only, leaving all the others unchanged. So I do this
para[1][0]=numpy.matrix([[1,1]])
The first index points to the second matrix in the list and the second index points to the first row in that matrix, replacing it with [1,1].
But strangely enough, this command changes the first row of ALL ten matrices in the list to [1,1] instead of just the second one like I wanted. What gives?
When you multiply the initial list by 10, you end up with a list of 10 numpy arrays which are in fact references to the the same underlying structure. Modifying one will modify all of them because in fact there's only one numpy array, not 10.
If you need proof, check out this example in the REPL:
>>> a = numpy.zeros(10)
>>> a = [numpy.zeros(10)]*10
>>> a[0] is a[1]
True
>>>
The is operator checks if both objects are in fact the same(not if they are equal in value).
What you should do is use a list comprehension to generate your initial arrays instead of a multiplication, like so:
para=[numpy.matrix(numpy.zeros((2,2))) for i in range(10)]
That will call numpy.matrix() ten times instead of just once and generate 10 distinct matrixes.