It looks like you just need a basic integer array indexing:
filter_indices = [1,3,5]
np.array([11,13,155,22,0xff,32,56,88])[filter_indices]
Answer from Joran Beasley on Stack OverflowVideos
It looks like you just need a basic integer array indexing:
filter_indices = [1,3,5]
np.array([11,13,155,22,0xff,32,56,88])[filter_indices]
numpy.take can be useful and works well for multimensional arrays.
import numpy as np
filter_indices = [1, 2]
array = np.array([[1, 2, 3, 4, 5],
[10, 20, 30, 40, 50],
[100, 200, 300, 400, 500]])
axis = 0
print(np.take(array, filter_indices, axis))
# [[ 10 20 30 40 50]
# [100 200 300 400 500]]
axis = 1
print(np.take(array, filter_indices, axis))
# [[ 2 3]
# [ 20 30]
# [200 300]]
Use slicing:
>>> arr = np.array([['1A34', 'RBP', 0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
['1A9N', 'RBP', 0.0456267, 0.0539268, 0.331932, 0.0464031,
4.41336e-06, 0.522107],
['1AQ3', 'RBP', 0.0444479, 0.201112, 0.268581, 0.0049757,
1.28505e-12, 0.480883],
['1AQ4', 'RBP', 0.0177232, 0.363746, 0.308995, 0.00169861, 0.0,
0.307837]], dtype=object)
>>> arr[:,:5:2]
array([['1A34', 0.0, 0.0],
['1A9N', 0.0456267, 0.331932],
['1AQ3', 0.0444479, 0.268581],
['1AQ4', 0.0177232, 0.308995]], dtype=object)
If the column indices are irregular then you can do something like this:
>>> indices = [0, 3, 4]
>>> arr[:, indices]
array([['1A34', 1.0, 0.0],
['1A9N', 0.0539268, 0.331932],
['1AQ3', 0.201112, 0.268581],
['1AQ4', 0.363746, 0.308995]], dtype=object)
Note that there's a subtle but substantial difference between slicing (which is basic indexing) and using a sequence for indexing (also known as advanced indexing or fancy indexing). When using a slice such as arr[:, :5:2], no data is copied, and we get a view of the original array. This implies that mutating the result of arr[:, :5:2] will affect arr itself. With fancy indexing arr[:, [0, 3, 4]] is guaranteed to be a copy: this takes up more memory, and mutating this result will not affect arr.
You can access the columns of a numpy array in the following way:
array[:,column_number]
To get the array of specific columns you can do as follows:
z = array([[['1A34', 'RBP', 0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
['1A9N', 'RBP', 0.0456267, 0.0539268, 0.331932, 0.0464031,
4.41336e-06, 0.522107],
['1AQ3', 'RBP', 0.0444479, 0.201112, 0.268581, 0.0049757,
1.28505e-12, 0.480883],
['1AQ4', 'RBP', 0.0177232, 0.363746, 0.308995, 0.00169861, 0.0,
0.307837]], dtype=object]) #your array here
op_array = array([ [z:,0], z[:,2], z[:,3] ])
The op_array will have the 0th, 2nd and 3rd columns as rows.
So you need to transpose it to get the output array in the desired format.
op_array.transpose()
op_array will now look as below:
op_array([['1A34', 0.0, 0.0],
['1A9N', 0.0456267, 0.331932],
['1AQ3', 0.0444479, 0.268581],
['1AQ4', 0.0177232, 0.308995])
Numpy uses multiple indexing, so instead of A[1][2][3], you can--and should--use A[1,2,3].
You might then think you could do A[:, second, third], but the numpy indices are broadcast, and broadcasting second and third (two one-dimensional sequences) ends up being the numpy equivalent of zip, so the result has shape (5, 2).
What you really want is to index with, in effect, the outer product of second and third. You can do this with broadcasting by making one of them, say second into a two-dimensional array with shape (2,1). Then the shape that results from broadcasting second and third together is (2,2).
For example:
In [8]: import numpy as np
In [9]: a = np.arange(125).reshape(5,5,5)
In [10]: second = [1,2]
In [11]: third = [3,4]
In [12]: s = a[:, np.array(second).reshape(-1,1), third]
In [13]: s.shape
Out[13]: (5, 2, 2)
Note that, in this specific example, the values in second and third are sequential. If that is typical, you can simply use slices:
In [14]: s2 = a[:, 1:3, 3:5]
In [15]: s2.shape
Out[15]: (5, 2, 2)
In [16]: np.all(s == s2)
Out[16]: True
There are a couple very important difference in those two methods.
- The first method would also work with indices that are not equivalent to slices. For example, it would work if
second = [0, 2, 3]. (Sometimes you'll see this style of indexing referred to as "fancy indexing".) - In the first method (using broadcasting and "fancy indexing"), the data is a copy of the original array. In the second method (using only slices), the array
s2is a view into the same block of memory used bya. An in-place change in one will change them both.
One way would be to use np.ix_:
>>> out = A[np.ix_(range(A.shape[0]),second, third)]
>>> out.shape
(5, 2, 2)
>>> manual = [A[i,j,k] for i in range(5) for j in second for k in third]
>>> (out.ravel() == manual).all()
True
Downside is that you have to specify the missing coordinate ranges explicitly, but you could wrap that into a function.
You can use boolean array indexing. First, create a mask of indices you want to set to 0 and then apply the mask to array and assign the replacement value (e.g., 0 in your case).
mask = b>np.arange(a.shape[1])[:,None]
a[~mask]=0
output:
array([[1, 2, 3],
[4, 0, 6],
[0, 0, 0]])
I think the issue is in a[:,b:]; here b: means little if b is not a scaler e.g. 5: means 6th onwards but [1,2,3]: means nothing when array is 2d.
It should be a[:,b]. Setting a[:,b] = 0 will set all columns specified in b to 0. Following is the run.
In [2]: import numpy as np
In [3]: a = np.array([[1, 2, 3],
...: [4, 5, 6],
...: [7, 8, 9]])
...:
...: b = np.array([2, 1, 2])
...:
In [4]: a
Out[4]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [5]: b
Out[5]: array([2, 1, 2])
In [6]: b.dtype
Out[6]: dtype('int64')
In [7]: a[:, b:] = 0
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-6e5050513225> in <module>
----> 1 a[:, b:] = 0
TypeError: only integer scalar arrays can be converted to a scalar index
In [8]: a[:, b] = 0
In [9]: a
Out[9]:
array([[1, 0, 0],
[4, 0, 0],
[7, 0, 0]])
But that's not what you want.
To get what you want, you need to specify rows indices and column indices e.g. (1,1), (2,0), (2,1), (2,2).
In [11]: a[[1,2,2,2], [1, 0, 1,2]] = 0
In [12]: a
Out[12]:
array([[1, 2, 3],
[4, 0, 6],
[0, 0, 0]])
Here is a method that use array broadcast:
x = np.random.randint(1, 63, 10)
y = np.random.randint(1, 63, 10)
dy, dx = [grid.astype(int) for grid in np.mgrid[-1:1:3j, -1:1:3j]]
Y = dy[None, :, :] + y[:, None, None]
X = dx[None, :, :] + x[:, None, None]
then you can use a[Y, X] to select blocks from a. Here is an example code:
img = np.zeros((64, 64))
img[Y, X] = 1
Here is graph ploted by pyplot.imshow():

A very straight forward solution would be a list comprehension and itertools.product:
import itertools
sub_arrays = [input_array[x-1:x+2, y-1:y+2]
for x, y in itertools.product(x_coords, y_coords)]
This creates all possible tuples of coordinates and then slices the 3x3 arrays from the input_array.
But this is sort-of a for loop. And you will have to take care, that x_coords and y_coords are not on the border of the matrix.
Use take():
In [87]: m = np.random.random((6, 2))
In [88]: m
Out[88]:
array([[ 0.6641412 , 0.31556053],
[ 0.11480163, 0.00143887],
[ 0.4677745 , 0.43055324],
[ 0.49749099, 0.15678506],
[ 0.48024596, 0.65701218],
[ 0.48952677, 0.97089177]])
In [89]: m.take([0, 2, 5], axis=0)
Out[89]:
array([[ 0.6641412 , 0.31556053],
[ 0.4677745 , 0.43055324],
[ 0.48952677, 0.97089177]])
You can pass a list or an array as indexes to any np array.
>>> r = np.random.randint(0,10,(5,5))
>>> r
array([[3, 8, 9, 8, 4],
[4, 1, 5, 9, 1],
[3, 6, 8, 8, 0],
[5, 1, 7, 6, 1],
[6, 1, 7, 7, 7]])
>>> idx = [0,3,1]
>>> r[idx]
array([[3, 8, 9, 8, 4],
[5, 1, 7, 6, 1],
[4, 1, 5, 9, 1]])