How can I logically test the output of a np.where result? - python-3.x

I was trying to scan an array for values and take action depending on the result. However, when I had a closer look at what the code was doing I noticed that my logical condition was ill posed.
I will illustrate what I mean with the following example:
#importing numpy
import numpy as np
#creating a test array
a = np.zeros((3,3))
#searching items bigger than 1 in 'a'
index = np.where(a > 1)
I was expecting my index to return an empty list. In fact it returns a tuple object, like:
index
Out[5]: (array([], dtype=int64), array([], dtype=int64))
So, the test I was imposing:
#testing if there are values
#in 'a' that fulfil the where condition
if index[0] != []:
print('Values found.')
#testing if there are no values
#in 'a' that fulfil the where condition
if index[0] == []:
print('No values found.')
Will not achieve its purpose because I was comparing different objects (is that correct to say?).
So what is the correct way to create this test?
Thanks for your time!

For your 2D array, np.where returns a tuple of arrays of indices (one for each axis), so that a[index] gives you an array of the elements fulfilling the condition.
Indeed, you compared an empty list to an empty array. Instead, I would compare the size property (or e.g. len()) of the first element of this tuple:
if index[0].size == 0:
print('No values found.')

Related

Get index of a list with tuples in which the first element of the tuple matches pattern

I have a list of tuples:
countries = [('Netherlands','31'),
('US','1'),
('Brazil','55'),
('Russia','7')]
Now, I want to find the index of the list, based on the first item in the tuple.
I have tried countries.index('Brazil'), I would like the output to be 2. But instead, that returns a ValueError:
ValueError: 'Brazil' is not in list
I am aware that I could convert this list into a pd DataFrame and then search for a pattern match within the first column. However, I suspect there is a faster way to do this.
You can use enumerate() to find your index:
Try:
idx = next(i for i, (v, *_) in enumerate(countries) if v == "Brazil")
print(idx)
Prints:
2

Is there a way to test if two separate values, in two separate arrays, and check if they are equal or not?

Im trying to see if a value in one array is equal to that in another array, the values are integer values.
Ive tried turning them into string and integers from the array but get the error that they cannot be converted implicitly.
winningnumber = []
usernumber = []
print(winningnumber)
print(usernumber)
if(winningnumber == usernumber):
print("Exact number")
I would then get an output like so
[1]
['1']
In order to do this, what you want to do is access the first item of each array, and compare that value.
There are a lot of ways to do this, but here is a little driver program to show you one way.
# Defining a function to see if they match
def is_winning(arr1, arr2):
# Grabbing the first element in each array
# denoted by the [0], for the "0th" element
arr1_first_ele = arr1[0]
arr2_first_ele = arr2[0]
# If the first element in the first array matches the first element in the second
if arr1_first_ele == arr2_first_ele:
# Print out they match
print("They match")
# Otherwise
else:
# Print out that they dont
print("They don't match")
def main():
# Example arrays
test_array_one = [1,3,4]
test_array_two = [5,4,3]
# This should print out "They don't match"
is_winning(test_array_one, test_array_two)
# Example arrays
test_array_three = [6,7,8]
test_array_four = [6,5,4]
# This should print out "They match"
is_winning(test_array_three, test_array_four)
main()
This evaluates to:
They don't match
They match

Finding multiple indexes but the array always has a length of 1

This seems trivial (again) but has me stumped.
I need to find the indexes of multiple values in a numpy array. I can do this with where and isin but the resulting answer always has a length of 1 regardless of how many indexes are found. Example
import numpy as np
a = [1,3,5,7,9,11,13,15]
b = [1,7,13]
x = np.where(np.isin(a,b))
print(x)
print(len(x))
this returns
(array([0, 3, 6]),)
1
I think its because the array is a single item inside a tuple. How do I return just the array?
Just use
x = np.where(np.isin(a,b))[0]
to get what you expect.
As hpaulj points out in the comments where returns a tuple with one array for each input array dimension, in this case there is only one, which is why x is a tuple of length one.

Function that removes zeroes from list?

I just need a function that removes zeroes from an input list
def no_zero(a):
pos=0
while (pos+1)<=len(a):
if a[pos] == "0":
a.remove[pos]
pos= pos +1
return a
print(no_zero([0,1,0,2,0,3]))
I should be getting an output of 1,2,3 but instead it skips right to return a. Any pointers as to why? Cheers.
You can use a list comprehension:
def no_zero(a):
return [x for x in a if x != 0]
print(no_zero([0,1,0,2,0,3]))
Additionally, the reason your code currently isn't working is because you are comparing the items to a string ("0") instead of an integer (0). You are also attempting to modify a list as you iterate over it, which means that your indices don't correspond to the original indices of the list, and your result will be wrong.

Getting a list item with the max evaluation in a list of tuples in Python

Given this list of tuples:
my_tuples = [(1,2), (3,4)]
and the following evaluation function:
def evaluate(item_tuple):
return item_tuple[0] * 2
Question: how can I get the list item (tuple) that has the highest evaluation value? (I'm guessing I can use a list comprehension for this)
def max_item(tuples_list, evaluation_fn):
'''Should return the tuple that scores max using evaluation_fn'''
# TODO Implement
# This should pass
assertEqual((3,4), max_item(my_tuples, evaluate))
Correct me if I'm wrong, you want the list of tuples sorted by the result of multiplying one of the values inside the tuple with x (in your example above it would be the first value of the tuple multiplied by 2).
If so, you can do it this way:
from operator import itemgetter
sorted(l, key=itemgetter(0 * 2), reverse=True)
I managed to do it this way:
def max_item(tuples_list, evaluation_fn):
zipped = zip(map(evaluation_fn, tuples_list), tuples_list)
return max(zipped, key=lambda i:i[0])[1]
I don't know if there's a simpler (more pythonic?) way to solve it though.
Edit
I figured how I could use a list comprehension to make it more succinct/readable:
def max_item(tuples_list, evaluation_fn):
return max([(evaluation_fn(i), i) for i in tuples_list])[1]

Resources