I assume your array looks like:
|(HUE)(VALUE)(CLASS)
row/col| 0 1 2
-------+-----------------
0 | 0 1 2
1 | 3 4 5
2 | 6 7 8
. | . . .
. | . . .
3599999| . . .
And here is the sample code. For simplicity I changed the size 3600000 to 5.
a = np.array(xrange(5 * 3))
a.shape = (5, 3)
Now array a look like this:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14]])
If you want row with HUE=9, do like this:
a[np.where(a[:,0] == 9)]
#array([[ 9, 10, 11]])
If you want row with VALUE=4, do like this:
a[np.where(a[:,1] == 4)]
#array([[3, 4, 5]])
If you want row with HUE=0 and VALUE=1, do like this:
a[np.where((a[:,0] == 0) * (a[:,1] == 1))]
#array([[0, 1, 2]])
Answer from Kei Minagawa on Stack OverflowI assume your array looks like:
|(HUE)(VALUE)(CLASS)
row/col| 0 1 2
-------+-----------------
0 | 0 1 2
1 | 3 4 5
2 | 6 7 8
. | . . .
. | . . .
3599999| . . .
And here is the sample code. For simplicity I changed the size 3600000 to 5.
a = np.array(xrange(5 * 3))
a.shape = (5, 3)
Now array a look like this:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14]])
If you want row with HUE=9, do like this:
a[np.where(a[:,0] == 9)]
#array([[ 9, 10, 11]])
If you want row with VALUE=4, do like this:
a[np.where(a[:,1] == 4)]
#array([[3, 4, 5]])
If you want row with HUE=0 and VALUE=1, do like this:
a[np.where((a[:,0] == 0) * (a[:,1] == 1))]
#array([[0, 1, 2]])
Try this code:
x[x[:, 2] == class_number[:, :2]
where x is np.ndarray
x[:, 2] == class_number
contains true/false that means whether the last is class_number or not.
You need to take a look at: Boolean indexing in http://wiki.scipy.org/Cookbook/Indexing
Moved from comment.
You can use np.isin() to check which elements in the first column are in the desired values list. You can then use the output as a mask.
import numpy as np
my_array = np.array([[1,55,4],
[2,2,3],
[3,90,2],
[4,65,1]])
desired_values = np.array([2,3,4])
mask = np.isin(element = my_array[:,0],test_elements = desired_values)
desired_array = my_array[mask]
print(desired_array)
output
array([[ 2, 2, 3],
[ 3, 90, 2],
[ 4, 65, 1]])
Edit: numpy.isin vs for-loop
@Furas suggested a for-loop solution. That approach works and is perhaps more intuitive, at least in that one does not have to research the many esoteric functions of Numpy.
My first reaction is to emphasize that Numpy operations tend to be faster than for-loops. However, the details are a little more nuanced. For-loops seem to be slightly faster for small arrays, but their time costs increase significantly faster as the size of the array increases.
Comparisons for relatively small test arrays
The first graph compares the computation times for np.isin() to those from the for-loop. The number of rows in my_array are presented along the x-axis. Their values are 2, 4, 6, ... 32.

The above graph shows that the computation time for the for-loop seems to increase linearly with the growth of the tested array. The for-loop is faster until the number of rows is approximately 10.
Comparisons for larger test arrays
The second graph shows a comparison similar to the first graph, but examines computation times when the number of rows in my_array is 2, 4, 8, 16, ... 1024.
The above graph shows that np.isin() is significantly faster and more appropriate for larger problems.
Code for reproduction
The data to recreate the above graphs may be generated with the following code.
import numpy as np
count_list = [2**x for x in range(2,11)]
isin_time_means = []
loop_time_means = []
for count in count_list:
my_array = np.random.randint(low=-10,high=10,size=(count,5))
desired_values = np.random.randint(low=-10,high = 10,size=(10,))
a = %timeit -o np.isin(my_array[:,0],desired_values)
b = %timeit -o [x in desired_values for x in my_array[:,0]]
isin_time_means.append(np.mean(a.timings))
loop_time_means.append(np.mean(b.timings))
You can always use for-loop to check every value separatelly
mask = [x in desiredValues for x in myArray[:,0]]
desired_array = myArray[mask]
Full code:
import numpy as np
myArray = np.array([[1,55,4],
[2,2,3],
[3,90,2],
[4,65,1]])
desiredValues = [2,3,4]
mask = [x in desiredValues for x in myArray[:,0]]
desired_array = myArray[mask]
print(desired_array)
python - Selecting specific rows and columns from NumPy array - Stack Overflow
Select certain rows (condition met), but only some columns in Python/Numpy - Stack Overflow
python - Numpy select rows based on condition - Stack Overflow
python - Selecting rows from a NumPy ndarray - Stack Overflow
As Toan suggests, a simple hack would be to just select the rows first, and then select the columns over that.
>>> a[[0,1,3], :] # Returns the rows you want
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[12, 13, 14, 15]])
>>> a[[0,1,3], :][:, [0,2]] # Selects the columns you want as well
array([[ 0, 2],
[ 4, 6],
[12, 14]])
[Edit] The built-in method: np.ix_
I recently discovered that numpy gives you an in-built one-liner to doing exactly what @Jaime suggested, but without having to use broadcasting syntax (which suffers from lack of readability). From the docs:
Using ix_ one can quickly construct index arrays that will index the cross product.
a[np.ix_([1,3],[2,5])]returns the array[[a[1,2] a[1,5]], [a[3,2] a[3,5]]].
So you use it like this:
>>> a = np.arange(20).reshape((5,4))
>>> a[np.ix_([0,1,3], [0,2])]
array([[ 0, 2],
[ 4, 6],
[12, 14]])
And the way it works is that it takes care of aligning arrays the way Jaime suggested, so that broadcasting happens properly:
>>> np.ix_([0,1,3], [0,2])
(array([[0],
[1],
[3]]), array([[0, 2]]))
Also, as MikeC says in a comment, np.ix_ has the advantage of returning a view, which my first (pre-edit) answer did not. This means you can now assign to the indexed array:
>>> a[np.ix_([0,1,3], [0,2])] = -1
>>> a
array([[-1, 1, -1, 3],
[-1, 5, -1, 7],
[ 8, 9, 10, 11],
[-1, 13, -1, 15],
[16, 17, 18, 19]])
Fancy indexing requires you to provide all indices for each dimension. You are providing 3 indices for the first one, and only 2 for the second one, hence the error. You want to do something like this:
>>> a[[[0, 0], [1, 1], [3, 3]], [[0,2], [0,2], [0, 2]]]
array([[ 0, 2],
[ 4, 6],
[12, 14]])
That is of course a pain to write, so you can let broadcasting help you:
>>> a[[[0], [1], [3]], [0, 2]]
array([[ 0, 2],
[ 4, 6],
[12, 14]])
This is much simpler to do if you index with arrays, not lists:
>>> row_idx = np.array([0, 1, 3])
>>> col_idx = np.array([0, 2])
>>> a[row_idx[:, None], col_idx]
array([[ 0, 2],
[ 4, 6],
[12, 14]])
>>> a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
>>> a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> a[a[:,0] > 3] # select rows where first column is greater than 3
array([[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> a[a[:,0] > 3][:,np.array([True, True, False, True])] # select columns
array([[ 5, 6, 8],
[ 9, 10, 12]])
# fancier equivalent of the previous
>>> a[np.ix_(a[:,0] > 3, np.array([True, True, False, True]))]
array([[ 5, 6, 8],
[ 9, 10, 12]])
For an explanation of the obscure np.ix_(), see https://stackoverflow.com/a/13599843/4323
Finally, we can simplify by giving the list of column numbers instead of the tedious boolean mask:
>>> a[np.ix_(a[:,0] > 3, (0,1,3))]
array([[ 5, 6, 8],
[ 9, 10, 12]])
If you do not want to use boolean positions but the indexes, you can write it this way:
A[:, [0, 2, 3]][A[:, 1] == i]
Going back to your example:
>>> A = np.array([[1,2,3,4],[6,1,3,4],[3,2,5,6]])
>>> print A
[[1 2 3 4]
[6 1 3 4]
[3 2 5 6]]
>>> i = 2
>>> print A[:, [0, 2, 3]][A[:, 1] == i]
[[1 3 4]
[3 5 6]]
Seriously,
Use a boolean mask:
mask = (z[:, 0] == 6)
z[mask, :]
This is much more efficient than np.where because you can use the boolean mask directly, without having the overhead of converting it to an array of indices first.
One liner:
z[z[:, 0] == 6, :]
Program:
import numpy as np
np_array = np.array([[0,4],[0,5],[3,5],[6,8],[9,1],[6,1]])
rows=np.where(np_array[:,0]==6)
print(np_array[rows])
Output:
[[6 8]
[6 1]]
And If You Want to Get Into 2d List use
np_array[rows].tolist()
Output of 2d List
[[6, 8], [6, 1]]
The following solution should be faster than Amnon's solution as wanted gets larger:
# Much faster look up than with lists, for larger lists:
wanted_set = set(wanted)
@numpy.vectorize
def selected(elmt): return elmt in wanted_set
# Or: selected = numpy.vectorize(wanted_set.__contains__)
print test[selected(test[:, 1])]
In fact, it has the advantage of searching through the test array only once (instead of as many as len(wanted) times as in Amnon's answer). It also uses Python's built-in fast element look up in sets, which are much faster for this than lists. It is also fast because it uses Numpy's fast loops. You also get the optimization of the in operator: once a wanted element matches, the remaining elements do not have to be tested (as opposed to the "logical or" approach of Amnon, were all the elements in wanted are tested no matter what).
Alternatively, you could use the following one-liner, which also goes through your array only once:
test[numpy.apply_along_axis(lambda x: x[1] in wanted, 1, test)]
This is much much slower, though, as this extracts the element in the second column at each iteration (instead of doing it in one pass, as in the first solution of this answer).
test[numpy.logical_or.reduce([test[:,1] == x for x in wanted])]
The result should be faster than the original version since NumPy's doing the inner loops instead of Python.