You can use np.where to return a tuple of arrays of x and y indices where a given condition holds in an array.
If a is the name of your array:
>>> np.where(a == 1)
(array([0, 0, 1, 1]), array([0, 1, 2, 3]))
If you want a list of (x, y) pairs, you could zip the two arrays:
>>> list(zip(*np.where(a == 1)))
[(0, 0), (0, 1), (1, 2), (1, 3)]
Or, even better, @jme points out that np.asarray(x).T can be a more efficient way to generate the pairs.
You can use np.where to return a tuple of arrays of x and y indices where a given condition holds in an array.
If a is the name of your array:
>>> np.where(a == 1)
(array([0, 0, 1, 1]), array([0, 1, 2, 3]))
If you want a list of (x, y) pairs, you could zip the two arrays:
>>> list(zip(*np.where(a == 1)))
[(0, 0), (0, 1), (1, 2), (1, 3)]
Or, even better, @jme points out that np.asarray(x).T can be a more efficient way to generate the pairs.
Using numpy, argwhere may be the best solution:
import numpy as np
array = np.array([[1, 1, 0, 0],
[0, 0, 1, 1],
[0, 0, 0, 0]])
solutions = np.argwhere(array == 1)
print(solutions)
>>>
[[0 0]
[0 1]
[1 2]
[1 3]]
Been messing around with numpy, trying to familiarize myself with it and seeing how I'd be able to utilize its arrays to store (very simple) map data for this text adventure game I've been working on. So far it seems like it'd be pretty darn useful, but I seem to have run into something of an issue.
My code is as follows (note: this is purposefully made with out a main class, because I am just trying to get the basic functionality down in my head before I incorporate it into my main program, and this is just easier for me):
# import numpy module as np
import numpy as np
# Establish the game map, a 3x3 grid of 0's
mainarray = np.array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
# Give feedback to make console easier to read
print(mainarray)
print("")
print("Placing player in center...")
# Place player on map (represented by a value of 1)
mainarray[1, 1] = 1
print(mainarray)
print("")
print("Locating player...")
# Attempt to find what the current index is of the value 1
print("")
print("Player is at index: ", np.where(mainarray == 1)[0][0])
In my head, I would like to eventually use this np.where() function (if I can) in one of the functions that moves my character. What I want to do is grab the current index of the "player" (represented by the number 1) and attempt to change that value to a 0, and change the value at an adjacent index to 1 (the tile that the player is moving to). Basically, I would like to use each index of the array as a sort of coordinate that I can take and use to move this "1" around the array, setting each index back to "0" after moving the "1", all based off user input.
Anyways, I am not getting any errors, however, the result that gets printed to the console is:
Player is at index: 1
Why is it just one number? It remains the same, even when I remove that second [0] in the last line. I don't fully understand how this function works, as this is the first time I've tried to use it, but since there are no errors, I have no clue what is going on.
Shouldn't I be receiving an index with two values, one for the column and one for the row? If not, how can I grab that as a result and use it in the way I described above? Is it even possible, or am I barking up the wrong tree with this function?
python - Finding indices of values in 2D numpy array - Stack Overflow
using np.where on a 2D array
How to find index of value in NumPy array? - Data Exploration & Visualization - Data Science Dojo Discussions
python - Find the index of a value in a 2D array - Stack Overflow
np.where with a single argument is equivalent to np.nonzero. It gives you the indices where a condition, the input array, is True.
In your example you are checking for element-wise equality between a[:,1] and values
a[:, 1] == values
False
So it's giving you the correct result: no index in the input is True.
You should use np.isin instead
np.isin(a[:,1], values)
array([False, False, True, True, False, False, False, False, True, False], dtype=bool)
Now you can use np.where to get the indices
np.where(np.isin(a[:,1], values))
(array([2, 3, 8]),)
and use those to address the original array
a[np.where(np.isin(a[:,1], values))]
array([[ 1, 97612, 1],
[ 1, 97697, 1],
[ 1, 97944, 1]])
Your initial solution with a simple equality check could indeed have worked with proper broadcasting:
np.where(a[:,1] == values[..., np.newaxis])[1]
array([2, 3, 8])
EDIT: given you seem to have issues with using the above results to index and manipulate your array here's a couple of simple examples
Now you should have two ways of accessing your matching elements in the original array, either the binary mask or the indices from np.where.
mask = np.isin(a[:,1], values) # np.in1d if np.isin is not available
idx = np.where(mask)
Let's say you want to set all matching rows to zero
a[mask] = 0 # or a[idx] = 0
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 0, 0, 0],
[ 0, 0, 0],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 0, 0, 0],
[ 1, 97955, 2]])
Or you want to multiply the third column of matching rows by 100
a[mask, 2] *= 100
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 1, 97612, 100],
[ 1, 97697, 100],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 1, 97944, 100],
[ 1, 97955, 2]])
Or you want to delete matching rows (here using indices is more convenient than masks)
np.delete(a, idx, axis=0)
array([[ 1, 97553, 1],
[ 1, 97587, 1],
[ 1, 97826, 3],
[ 1, 97832, 1],
[ 1, 97839, 1],
[ 1, 97887, 1],
[ 1, 97955, 2]])
Just a thought:
Try to flatten the 2D array and compare using numpy.intersect1d.
https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.ndarray.flatten.html
https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.intersect1d.html
I have a 2D array that is shaped like (10000,2). The rows in this array repeat so I call np.unique with axis=0, to get the 2D array of all the unique rows. This reduces the size down to (24,2) or something like that. Now, I have a vector and I want to find out which index in the reduced array it is equal to. So I call np.where(reduced == vector). This does not give me the row that it is equal. Rather it takes the input vector 1 number at a time and finds where in the reduced array the numbers match. This is OK since when there are two numbers that are the same consecutively, that equates to the index that I want. So I just call np.ediff1d and find where that equals 0. I was wondering if there is an easier way to do this? Thanks. Example code is given.
import numpy as np reduced = [[10,2],[15,3],[10,1],[16,5],[16,3]] vector = [15,3] results = np.where(reduced == vector) # I want the output to be 1 but I get # results[0] = [1,1,4] diffs = np.ediff1d(results[0]) # this results in [0,3] index_that_matchs = np.where(diffs == 0)[0][0] index = results[0][index_that_matchs] # this results in 1
Loop through your list and search each sublist for the string.
Testlist = [
["Romeo and Juliet","Shakespeare"],
["Othello","Play"],
["Macbeth","Tragedy"]
]
Value = "Tragedy"
for index, lst in enumerate(Testlist):
if Value in lst:
print( index, lst.index(Value) )
You can also use the map operator:
# Get a boolean array - true if sublist contained the lookup value
value_in_sublist = map(lambda x: value in x, test_list)
# Get the index of the first True
print(value_in_sublist.index(True))