Greg Sullivan
Greg Sullivan

Reputation: 183

Using booleans in Python

I am trying to replace string values in an array with the array median, but I am getting an error code when I try to make a boolean. I have a defined array with 3 string values and the code I am trying to enter is:

arr2 = np.array ([1,2,3,1,5,2,3,4,2,
                  4,1,3,4,1,2,5,3,2,
                  1,"?",1,"n",3,2,5,
                  1,2,"Nan",3,2,2,4,3])

flag_good = [element.isdigit() for element in arr2]
flag_bad = ~flag_good

but I get an error code when running the line:

flag_bad = ~flag_good

How would I go about replacing the sting values with the array's median?

Upvotes: 2

Views: 100

Answers (2)

gust
gust

Reputation: 945

I feel like you could solve the problem from the beginning, editing your list comprehension.

flag_bad = [not(element.isdigit()) for element in arr2]

To answer your question, though, I'd do this:

import numpy as np
input_list = [1,2,3,1,5,2,3,4,2,
                  4,1,3,4,1,2,5,3,2,
                  1,"?",1,"n",3,2,5,
                  1,2,"Nan",3,2,2,4,3]

# calculate the median
median = int(np.median([elt for elt in input_list if type(elt) is int])) 

# replace elements of the list only if you have a non-int 
output_array = np.array([elt if type(elt) is int else median for elt in input_list])
print(output_array)

Output:

[1 2 3 1 5 2 3 4 2 4 1 3 4 1 2 5 3 2 1 2 1 2 3 2 5 1 2 2 3 2 2 4 3]

Upvotes: 1

Querenker
Querenker

Reputation: 2365

The tilde operation is part of numpy and is a shortcut for numpy.invert.

By using a list comprehension, flag_good is a Python list, which doesn't support this operation.

For example, you can convert the list flag_good to a Numpy array and then use the invert function.

>>> flag_bad = ~np.array(flag_good)
>>> flag_bad
array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False,  True, False,  True, False, False, False, False, False,
        True, False, False, False, False, False])

Or you can use vectorize and directly return a Numpy array where the function is called elementwise instead of using the list comprehension.

>>> flag_good = np.vectorize(lambda x: x.isdigit())(arr2)
>>> flag_bad = ~flag_good
>>> flag_bad
array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False,  True, False,  True, False, False, False, False, False,
        True, False, False, False, False, False])

Upvotes: 3

Related Questions