replacing values in a whole array - python

I would like to ask how I can change the values in a whole NumPy array.
For example I want to change every value which is < 1e-15 to be equal to 1e-15.

Assuming you mean a numpy array, and it's pointed to by a variable a:
np.fmax(a, 1e-15, a)
This finds the maximum of the two values given as the first two arguments (a and 1e-15) on a per-element basis, and writes the result back to the array given as the third argument, a.
I had a hard time finding the official docs for this function, but I found this.

If L is a list:
L[:] = [max(x, 10e-15) for x in L]

Assuming you mean a lsit instead of an array, I'd recommend to use a list comprehension:
new_list = [max(x, 1e-15) for x in my_list]
(I also assume you mean 1e-15 == 10. ** (-15) instead of 10e-15 == 1e-14.)
There also exist "arrays" in Python: The class array.array from the standard library, and NumPy arrays.

I like numpy.fmax (which was new to me), but for a possibly more generic case, I often use:
a[a < 1e-15] = 1e-15
(More generic in the sense that you can vary the condition, or that the replacement value is not equal to the comparison value.)

Related

What is the [x] in a "Function()[x]" in Python?

I only want to know what is the meaning of [x] in a function (In general, not about the code that I will show), which I always think as a list but found nothing about it.
I will show two codes that I have seen using it, the first one is using PyTorch Library (Convolution):
Short one:
x.size()[0]
Long one:
def forward(self, x):
conv_out = self.conv(x).view(x.size()[0], -1)
return self.fc(conv_out)
The second one is using GYM library for RL, but also part of the code above:
Short one:
assert env.unwrapped.get_action_meanings()[1] == 'FIRE'
Long one:
def __init__(self, env=None):
"""For environments where the user need to press FIRE for the game to start."""
super(FireResetEnv, self).__init__(env)
assert env.unwrapped.get_action_meanings()[1] == 'FIRE'
assert len(env.unwrapped.get_action_meanings()) >= 3
I don't want to know why they are using the function()[x], I only want to know what is the [x] in general.
Thank for the answer.
[] is the indexing operator in Python.
If you have a list or tuple l, l[n] means the nth element of it.
If you have a dictionary d, d[x] means the element whose key is x.
If you have a string s, s[n]means then`th character in the string.
Some other datatypes define their own indexing functions, but they generally implement the same idea, possibly extending it (Numpy arrays allow you to use a tuple to perform multi-dimensional indexing and slicing).
If you put [x] after a function call, it performs the indexing on whatever the function returns.
y = function()[x]
is equivalent to
temp = function()
y = temp[x]
The [x] that comes after the several types of input you describe is simply an index reference. It can apply to lists, tuples or dicts, depending on how you use them. For example:
z = np.zeros((2, 3)) #Creates a numpy array of zeros with size (2, 3)
print(z.size()) #Outputs (2, 3)
print(z.size()[0]) #outputs the 0th index of the tuple
print(z.size()[2]) #Returns index error as it is out of range
The same applies for lists and dicts but comes with varied problems. Most of the time, for functions, this is used only if you know what is the format of the return value and you only need a part of it.
Hope this helps.

Sum of Boolean List in Python not functioning as expected

I understand that python can treat 'True' as '1' (as do many coding languages) and as such taking the sum() of a list should return the number of trues in the list.
(as demonstrated in Counting the number of True Booleans in a Python List)
I'm new to Python and have been going through some of the ISLR application exercises in Python (http://www.springer.com/us/book/9781461471370).
Chapter 2, problem 10 (h) has a pretty simple question asking for the number of observations of a variable ('rm') that are greater than 7. I would expect the following code to work:
test = [Boston['rm'] > 7]
sum(test)
However this returns the entire list "test" with 0's and 1's, not its sum. Can anyone explain why?
(note Boston is from the Boston data set from the MASS package in R)
If I use a tuple or numpy array instead of a list it works just fine; for example:
test2 = (Boston['rm'] > 7)
sum(test2)
test3 = np.array(Boston['rm'] > 7)
sum(test3)
Also "test" seems to be a proper Boolean list because the following code using it to subset "Boston" also works fine:
test4 = Boston[Boston['rm'] > 7]
len(test4)
While I have clearly found several methods that work, I'm confused why the first did not. Thanks in advance.
If I use a tuple or numpy array instead of a list it works just fine; for example:
test2 = (Boston['rm'] > 7)
sum(test2)
test3 = np.array(Boston['rm'] > 7)
sum(test3)
(Boston['rm'] > 7) uses parentheses for grouping; it isn’t a tuple. The tuple equivalent would be (Boston['rm'] > 7,) (note the comma), and it breaks in the same way as the list does. Using np.array on an array doesn’t change it – it’s like the difference between list(5) and [5].
As for why it doesn’t work: Boston['rm'] > 7 is an array, so you want to get its sum directly. Wrapping it in another list means you’re taking the sum of a list of arrays and not a list of booleans.

Check if list of numpy arrays are equal

I have a list of numpy arrays, and want to check if all the arrays are equal. What is the quickest way of doing this?
I am aware of the numpy.array_equal function (https://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.array_equal.html), however as far as I am aware this only applies to two arrays and I want to check N arrays against each other.
I also found this answer to test all elements in a list: check if all elements in a list are identical.
However, when I try each method in the accepted answer I get an exception (ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all())
Thanks,
You could simply adapt a general iterator method for your array comparison
def all_equal(iterator):
try:
iterator = iter(iterator)
first = next(iterator)
return all(np.array_equal(first, rest) for rest in iterator)
except StopIteration:
return True
If this is not working, it means that your arrays are not equal.
Demo:
>>> i = [np.array([1,2,3]),np.array([1,2,3]),np.array([1,2,3])]
>>> print(all_equal(i))
True
>>> j = [np.array([1,2,4]),np.array([1,2,3]),np.array([1,2,3])]
>>> print(all_equal(j))
False
You can use np.array_equal() in a list comprehension to compare each array to the first one:
all([np.array_equal(list_of_arrays[0], arr) for arr in list_of_arrays])
If your arrays are of equal size, this solution using numpy_indexed (disclaimer: I am its author) should work and be very efficient:
import numpy_indexed as npi
npi.all_unique(list_of_arrays)
#jtr's answer is great, but I would like to suggest a slightly different alternative.
First of all, I think using array_equal is not a great idea, because you could have two arrays of floats and maybe you can end up having very small differences that you are willing to tolerate, but array_equal returns True if and only if the two arrays have the same shape and exact same elements. So let's use allclose instead, which allows to select the absolute and relative tolerances that meet your needs.
Then, I would use the built-in zip function, which makes the code more elegant.
Here is the code:
all([np.allclose(array, array_expected), for array, array_expected in zip(array_list, array_list_expected)])
I guess you can use the function unique.
http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.unique.html#numpy.unique
if all sub-arrays in the array is the same, it should return only one item.
Here's better described how to use it.
Find unique rows in numpy.array

Convert array to python scalar

I need big help, please check out this code:
import.math
dose =20.0
a = [[[2,3,4],[5,8,9],[12,56,32]]
[[25,36,45][21,65,987][21,58,89]]
[[78,21,98],[54,36,78],[23,12,36]]]
PAC = math.exp(-dose*a)
this what I would like to do. However the error I am getting is
TypeError: only length-1 arrays can be converted to Python scalars
If you want to perform mathematical operations on arrays (whatever their dimensions...), you should really consider using NumPy which is designed just for that. In your case, the corresponding NumPy command would be:
PAC = numpy.exp(-dose*np.array(a))
If NumPy is not an option, you'll have to loop on each element of a, compute your math.exp, store the result in a list... Really cumbersome and inefficient. That's because the math functions require a scalar as input (as the exception told you), when you're passing a list (of lists). You can combine all the loops in a single list comprehension, though:
PAC = [[[math.exp(-dose*j) for j in elem] for elem in row] for row in a]
but once again, I would strongly recommend NumPy.
You should really use NumPy for that.
And here is how you should do it using nested loops:
>>> for item in a:
... for sub in item:
... for idx, number in enumerate(sub):
... print number, math.exp(-dose*number)
... sub[idx] = math.exp(-dose*number)
Using append is slow, because every time you copy the previous array and stack the new item to it.
Using enumerate, changes numbers in place. If you want to keep a copy of a, do:
acopy = a[:]
If you don't have much numbers, and NumPy is an over kill, the above could be done a tiny bit faster using list comprehensions.
If you want, for each element of the array to have it multiplied by -dose then apply math.exp on the result, you need a loop :
new_a = []
for subarray in a:
new_sub_array = []
for element in sub_array:
new_element = math.exp(-dose*element)
new_sub_array.append(new_element)
new_a.append(new_sub_array)
Alternatvely, if you have a mathlab background, you could inquire numpy, that enable transformations on array.

Python integer infinity for slicing

I have defined a slicing parameter in a config file:
max_items = 10
My class slices a list according to this parameter:
items=l[:config.max_itmes]
When max_items = 0, I want all items to be taken from l. The quick and dirty way is:
config.max_items=config.max_items if config.max_items>0 else 1e7
Assuming that there will be less then 1e7 items. However, I don't fancy using magic numbers. Is there a more Pythonic way of doing it, like an infinity integer constant?
There is no "infinity integer constant" in Python, but using None in a slice will cause it to use the default for the given position, which are the beginning, the end, and each item in sequence, for each of the three parts of a slice.
>>> 'abc'[:None]
'abc'
Have you tried with sys.maxint?

Categories

Resources