I have a numpy array arr of numpy arrays each with varying length. I can get the shape of arr:
arr.shape
>>> (9,)
I can get the shape of one of the elements of arr:
arr[0].shape
>>> (6, 1, 2)
And I know that all such elements have shape (n, 1, 2).
I want to slice arr to get a 1 dimensional result as follows:
arr[:,:,:,0]
But I get the following error:
IndexError: too many indices for array
EDIT: My original question was misleading. I want to do this slice so that I can assign values to the slice. So getting the slice in a new variable is not useful for my case. Essentially I want to do something like this in a simple one liner:
arr[:,:,:,0] = arr[:,:,:,0] - np.min(arr[:,:,:,0])
You can fix your first (in fact all varying ones) dimension, and apply your transformation per static-shaped elements of arr
import numpy as np
from random import randint
arr=np.array([np.random.randint(3,15, size=(randint(3,9),randint(3,7),randint(6,19))) for el in range(9)])
print(arr.shape)
print(arr[0].shape)
for i in range(arr.shape[0]):
arr[i][:,:,0]-=arr[i][:,:,0].min()
print(arr[i][:,:,0])
You could use list comprehension version of your solution.
desired_result = np.array([el[:,:,0] for el in arr])
Related
Given a list of numpy arrays, each of different length, as that obtained by doing lst = np.array_split(arr, indices), how do I get the sum of every array in the list? (I know how to do it using list-comprehension but I was hoping there was a pure-numpy way to do it).
I thought that this would work:
np.apply_along_axis(lambda arr: arr.sum(), axis=0, arr=lst)
But it doesn't, instead it gives me this error which I don't understand:
ValueError: operands could not be broadcast together with shapes (0,) (12,)
NB: It's an array of sympy objects.
There's a faster way which avoids np.split, and utilizes np.reduceat. We create an ascending array of indices where you want to sum elements with np.append([0], np.cumsum(indices)[:-1]). For proper indexing we need to put a zero in front (and discard the last element, if it covers the full range of the original array.. otherwise just delete the [:-1] indexing). Then we use the np.add ufunc with np.reduceat:
import numpy as np
arr = np.arange(1, 11)
indices = np.array([2, 4, 4])
# this should split like this
# [1 2 | 3 4 5 6 | 7 8 9 10]
np.add.reduceat(arr, np.append([0], np.cumsum(indices)[:-1]))
# array([ 3, 18, 34])
I'd like to be able to reference an element of a Numpy n-dimensional array when the shape of the array itself is variable.
For a 4-D array, I know I'd be able to access some specific element index (let's say the very first one for argument) by direct referencing, for example
array[1, 1, 1, 1]
But what if the next iteration I only had a 3-dimension array? I'd need;
array[1, 1, 1]
And then a 6-dimension array? Then I'd need
array[1, 1, 1, 1, 1, 1]
Assuming that I know the appropriate index for each case, how do I go about programatically referencing array indices when the shape can change?
Thanks
you can always reshape the array and expand the index:
import numpy as np
a = np.arange(10*100*77*10*10).reshape(10,100,77,10,10)
print(a[1,2,5,9,9])
#output: 785999
def new_index(index, array):
shape = array.shape
terms = [v*np.prod(shape[i+1:]) for i,v in enumerate(index)]
return int(sum(terms))
# make a 1-D array
oneD = a.reshape(np.prod(a.shape))
print(oneD[new_index([1,2,5,9,9], a)])
#output: 785999
I'm assuming there's a numpy function that does this but I don't know it off the top of my head
hpaulj had the answer I was after. I'd tried referencing via a list (created by appending values with increasing dimension), but not via a tuple.
With the variable dimension index to be accessed as a list, first convert to a tuple, and then reference;
list_index = [1,1,1,1]
tuple_index = tuple(list_index)
result = array[tuple_index]
My array looks like this:
a = ([1,2],[2,3],[4,5],[3,8])
I did the following to delete odd indexes :
a = [v for i, v in enumerate(a) if i % 2 == 0]
but it dives me now two different arrays instead of one two dimensional:
a= [array([1, 2]), array([4, 5])]
How can I keep the same format as the beginning? thank you!
That is as simple as
a[::2]
which yields the lines with even index.
Use numpy array indexing, not comprehensions:
c = a[list(range(0,len(a),2)),:]
If you define c as the output of a list comprehension, it will return a list of one-dimensional numpy arrays. Instead, using the proper indexing maintains the result a numpy array.
Note than instead of "deleting" the odd indices, what we do is specify what to keep: take all lines with an even index (the list(range(0,len(a),2)) part) and for each line take all elements (the : part)
I want to count easily the number of elements in a NumPy array, but I don't know a priori their dimensions. Is there a generic function that counts the number of elements in a numpy array whatever its dimension is?
Thanks
numpy.ndarray.size returns a number of elements in the array
>>> x = np.zeros((3, 5, 2), dtype=np.complex128)
>>> x.size
30
I have a numpy array and I want to delete the first 3 elements of the array. I tried this solution:
a = np.arange(0,10)
i=0
while(i<3):
del a[0]
i=i+1
This gives me an error that "ValueError: cannot delete array elements". I do not understand why this is the case. i'd appreciate the help thanks!
Numpy arrays have a fixed size, hence you cannot simply delete an element from them. The simplest way to achieve what you want is to use slicing:
a = a[3:]
This will create a new array starting with the 4th element of the original array.
For certain scenarios, slicing is just not enough. If you want to create a subarray consisting of specific elements from the original array, you can use another array to select the indices:
>>> a = arange(10, 20)
>>> a[[1, 4, 5]]
array([11, 14, 15])
So basically, a[[1,4,5]] will return an array that consists of the elements 1,4 and 5 of the original array.
It works for me:
import numpy as np
a = np.delete(a, k)
where "a" is your numpy arrays and k is the index position you want delete.
Hope it helps.
numpy arrays don't support element deletion. Why don't you just use slicing to achieve what you want?
a = a[3:]
You can convert it into a list and then try regular delete commands like pop, del, eg.
a = np.array([1,2,3,4,5])
l = list(a)
l.pop(3)
l
>>[1, 2, 3, 5]