Here is my code:
test_list= [
["Romeo and Juliet","Shakespeare"],
["Othello","Play"],
["Macbeth","Tragedy"]
]
value = "Tragedy"
print(test_list.index(value))
As a result I get “ValueError: ‘Tragedy’ is not in list
I’d come to the conclusion that .index only works for 1D arrays? But then how do I do it die 2D arrays? This code works fine if I make the array 1D. Please help, but in simple terms as I am a beginner.
Apologies for formatting issues on mobile. The array is set out correctly for me.
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))
You can also use numpy:
import numpy as np
test_list = np.array(test_list)
value = 'Tragedy'
print(np.where(test_list == value))
Output:
(array([2]), array([1]))
If you have multiple occurences of an element, then np.where will give you a list of indices for all the occurences.
numpy arrays may help in your specific case
import numpy
test_array = numpy.array(Testlist)
value = "Tragedy"
numpy.where(test_array==value)
# you will get (array([2]), array([1]))
Related
I am wondering whether there is a way to filter a multidimensional array with an list of indexes.
For example, if there is a multidimensional array as so [[40,60,15],[25,30,45]], I want to obtain the resulting values when you filter with the following index [(0,2),(1,0)]. Note that the index is a list of tuples
Note : I am trying to find out the fastest method of doing this. I managed to do this using a for loop and map + lambda function,
however was wondering if numpy broadcasting was a possibility?
from numpy import np
some_arr = np.array([40,60,15],[25,30,45])
some_idx = [(0,2),(1,0)]
#Method 1 : Using for loop
new_list = []
for idx in some_idx:
new_list.append(some_arr[idx])
# Method 2: Using lambda
new_list = list(map(lambda idx : some_arr[idx], some_idx))
# Method 3 : Using numpy ??? (i get an error ofcourse but this is what I tried to do)
new_arr = some_arr[some_idx]
And I end up with an error for method 3 : index 2 is out of bounds for axis 0 with size 2
The output for this example should be [15,25]
Use zip to instead have tuple of ((x_0, x_1...),(y_0,y_1...)) indices, which you can then use to perform integer array indexing along both axes:
some_arr = np.array([[40,60,15],[25,30,45]])
some_idx = [(0,2),(1,0)]
some_arr[tuple(zip(*some_idx))]
# array([15, 25])
Comparing with your first method:
new_list = []
for idx in some_idx:
new_list.append(some_arr[idx])
np.array_equal(new_list, some_arr[tuple(zip(*some_idx))])
# True
Lets say I have a numpy array:
arr = np.array([1,2,3,4,9,11])
and I would like to find elements of a target array say:
target = np.array([3,10])
that are closest to the elements of the original array. So the the results is going to be:
[3,3,3,3,10,10]
Because 1,2,3,4 are matched to 3 of the target array and 9,11 were matched to 10.
Is there a function in scipy/numpy to do that?
There is no direct function just for that I think. This one-liner can do what you want.
First select the indices with minimum difference and take the values from target array.
arr = target[abs(arr[None, :] - target[:, None]).argmin(axis=0)]
import numpy as np
ar = np.array([1,2,3,4,9,11])
tar = np.array([3,10])
def target(arr,target):
ans=np.empty([len(arr)], dtype=int)
for elem in range(arr.size):
dist=[]
for ele in range(target.size):
dist.append(abs(target[ele]-arr[elem]))
ans[elem]=target[dist.index(min(dist))]
return ans
print(target(ar,tar))
Hope this helps.
I want to find a maximum elements index in a nested list for each row.
I got this error:
maxe = array[i].index(max(e_object.x for e_object in array[i]))
ValueError: 5 is not in list
class e_object():
def __init__(self,x):
self.x = x
array = []
array.append( [])
array[0].append(e_object(0))
array[0].append(e_object(2))
array[0].append(e_object(-3))
array[0].append(e_object(5))
array.append( [])
array[1].append(e_object(0))
array[1].append(e_object(2))
array[1].append(e_object(8))
array[1].append(e_object(5))
max_array = []
for i in range(len(array)):
maxe = array[i].index(max(e_object.x for e_object in array[i]))
max_array.append(maxe)
print(max_array)
How can I get this result?
[3,2]
Use a list comprehension to convert the nested list into one of x values, and then use np.argmax:
import numpy as np
np.argmax([[element.x for element in row] for row in array], axis=1)
Output:
array([3, 2], dtype=int64)
The problem is line
maxe = array[i].index(max(e_object.x for e_object in array[i]))
You are asking the index of object.x, but the list actually contains object. Change the max function to look inside the objects x attribute
maxe = array[i].index(max(array[i], key=lambda o: o.x))
The error happens because your max effectively operates on a list of integers [0, 2, -3, 5], while index searches in a list of e_objects. There are any number of ways of fixing this issue.
The simplest is probably to just have max return the index:
max_array = [max(range(len(a)), key=lambda x: a[x].x) for a in array]
This is very similar to using numpy's argmax, but without the heavy import and intermediate memory allocations. Notice that this version does not require two passes over each list since you don't call index on the result of max.
A more long term solution would be to add the appropriate comparison methods, like __eq__ and __gt__/__lt__ to the e_object class.
I have a data set which is a list of lists, looking like this:
[[-0.519418066, -0.680905835],
[0.895518429, -0.654813183],
[0.092350219, 0.135117023],
[-0.299403315, -0.568458405],....]
its shape is (9760,) and I am trying to remove all entries where the value of the first number in each entry is greater than 0, so in this example the 2nd and 3rd entries would be removed to leave
[[-0.519418066, -0.680905835],
[-0.299403315, -0.568458405],....]
So far I have written:
for x in range(9670):
for j in filterfinal[j][0]:
if filterfinal[j][0] > 0:
np.delete(filterfinal[j])
this returns: TypeError: list indices must be integers or slices, not list
Thanks in advance for any help on this problem!
You can use numpy's boolean indexing:
>>> x = np.random.randn(10).reshape((5,2))
array([[-0.46490993, 0.09064271],
[ 1.01982349, -0.46011639],
[-0.40474591, -1.91849573],
[-0.69098115, 0.19680831],
[ 2.00139248, -1.94348869]])
>>> x[x[:,0] > 0]
array([[ 1.01982349, -0.46011639],
[ 2.00139248, -1.94348869]])
Some explanation:
x[:,0] selects the first column of your array.
x > 0 will return an array of the same shape where each value is replaced by the result of the element-wise comparison (i.e., is the value > 0 or not?)
So, x[:,0] > 0 will give you an array of shape (n,1) with True or False values depending on the first value of your row.
You can then pass this array of booleans as an index to your original array, where it will return you an array of only the indexes that are True. By passing in a boolean array of shape (n,1), you select per row.
You are talking about "shape", so I assume that you are using numpy. Also, you are mentioning np in your example code, so you are able to apply element wise operations together with boolean indexing
array = np.array([[-0.519418066, -0.680905835],
[0.895518429, -0.654813183],
[0.092350219, 0.135117023],
[-0.299403315, -0.568458405]])
filtered = array[array[:, 0] < 0]
Use a list comprehension:
lol = [[-0.519418066, -0.680905835],[0.895518429, -0.654813183],[0.092350219, 0.135117023],[-0.299403315, -0.568458405]]
filtered_lol = [l for l in lol if l[0] <= 0]
You can use a list comprehension that unpacks the first item from each sub-list and retains only those with the first item <= 0 (assuming your list of lists is stored as variable l):
[l for a, _ in l if a <= 0]
You can go through this in a for loop and making a new list without the positives like so:
new_list = []
for item in old_list:
if item[0] < 0:
new_list.append(item)
But I'd prefer to instead use the in built filter function if you are comfortable with it and do something like:
def is_negative(number):
return number < 0
filtered_list = filter(is_negative, old_list)
This is similar to a list comprehension - or just using a for loop. However it returns a generator instead so you never have to hold two lists in memory making the code more efficient.
I have a numpy array as follows :
Keys which will store some values. for example
Keys [2,3,4,7,8]
How to get index of 4 and store the index in a int variable ?
For example the index value of 4 is 2, so 2 will be stored in a int variable.
I have tried with following code segment
//enter code here
for i in np.nditer(Keys):
print(keys[i]);
//enter code here
I am using python 3.5
Spyder 3.5.2
Anaconda 4.2.0
Is keys a list or numpy array
keys = [[2,3,4,7,8] # or
keys = np.array([2,3,4,7,8])
You don't need to iterate to see the elements of either. But you can do
for i in keys:
print(i)
for i in range(len(keys)):
print(keys[i])
[i for i in keys]
these work for either.
If you want the index of the value 4, the list has a method:
keys.index(4)
for the array
np.where(keys==4)
is a useful bit of code. Also
np.in1d(keys, 4)
np.where(np.in1d(keys, 4))
Forget about np.nditer. That's for advanced programming, not routine iteration.
There are several ways. If the list is not too large, then:
where_is_4 = [e for i,e in enumerate(Keys) if i==4][0]
What this does is it loops over the list with an enumerator and creates a list that contains the value of the enumerator every time the value '4' occurs.
Why not just do:
for i in range( len( Key ) ):
if ( Key[ i ] == 4 ):
print( i )
You can find all indices where the value is 4 using:
>>> keys = np.array([2,3,4,7,8])
>>> np.flatnonzero(keys == 4)
array([2])
There is a native numpy method for this called where.
It will return an array of the indices where some given condition is true. So you can just pick the first entry, if the list isn't empty:
N = 4
indicies = np.where(x==N)[0]
index = None
if indicies:
index = indicies[0]
Use of numpy.where(condition) will be a good choice here. From the below code you can get location of 4.
import numpy as np
keys = np.array([2,3,4,7,8])
result = np.where(keys==4)
result[0][0]