inverse elements except for zero in a numpy vector - python

In python, I'm trying to inverse a numpy vector except for these elements with zero values.
I used vectorize function, but always got a wrong answer when the first element is zero, (the code works well when zeros are not in the first position ).
active_N=np.array([0,1,3,5])
f=np.vectorize(lambda x:x if x==0 else 1./x)
active_N_inverse=f(active_N)
Run the code then I get
array([0, 0, 0, 0])
What was wrong with the codes above?
Is there any other method to solve this problem with high efficiency?

Use np.divide with a where clause:
np.divide(1, active_N, where=active_N!=0)
Optionally combined with round:
np.divide(1, active_N, where=active_N!=0).round(100)
Output:
array([0. , 1. , 0.33333333, 0.2 ])

Related

Deleting values from array with np.diff

I need to edit an array. The array has two columns. One for X-Values, the other for Y-Values. The X-Values are 0.0025 steps (0, 0.0025, 0.005, etc.) but sometimes there are wrong steps and I need to delete those. The others recommend that I use the following:
data = data[~np.r_[True, (np.diff(data[:,0])>0)&(np.diff(data[:, 0])<0.0024)]]
The problem is that the first value always gets deleted and the second problem is that it doesn´t just delete the wrong step but the one after it too.
The reason the first element is always being deleted is because you invert the output of np.r_ which prepends True to the output of np.diff. When using ~, that gets turned into a False, and thus the first element gets deleted.
My guess that the step after gets deleted too is because np.diff checks the difference between consecutive elements. Consider:
0.0025, 0.005, 0.008, 0.01, 0.0125
~~~~~
# The diff here is going to look like:
0.0025, 0.003, 0.002, 0.0025
Note how the wrong element results in a wrong diff both before AND after that element.
If that is unexpected behavior, then you should not use np.diff, instead compare with the expected steps directly using np.arange
import numpy as np
# Solution:
data[ np.isclose(data[:, 0], np.arange(start, stop, 0.0025)) ]
# with I'm guessing start=0, and stop=data.shape[0]*0.0025

How to round a specific selection of numbers in numpy array?

From the random numpy list, I want to round only the numbers that are in the index of padInputs. The following code is something that I am trying but doesn't work. What would be a workaround?
padInputs = [0, 2, 7, 8]
random = np.random.rand(13)
for padInput in padInputs:
np.around(random[padInput])
For example,
Input
[0.87720789, 0.88194004, 0.06039337, 0.13874861, 0.85552875]
Output
[0.87720789, 1, 0, 0.13874861, 0.85552875]
Try this way:
random[padInputs] = np.around(random[padInputs])
Note that this will round without decimals, you can pass it as an argument to round in the following way:
random[padInputs] = np.around(random[padInputs], decimals=2)
Problem in your code is you have to assign result back to array as np.around is not in memory function.
like
for padInput in padInputs:
random[padInput] = np.around(random[padInput])
random
array([1. , 0.53206402, 1. , 0.18129529, 0.71238687,
0.92995779, 0.21934659, 0. , 1. , 0.26042076,
0.76826639, 0.82750894, 0.35687544])
but it should be replace by one line as #Bruno define in his answer.
The following one-line piece of code can replace your for loop and does exactly what you want
np.put(random, padInputs, np.around(random))

Get multiple return values from numba vectorize

I am wondering if it is possible to get multiple return values from a function compiled with numba.vectorize.
I am using the vectorize decorator for a function that takes in a series of arguments, and performs and iterative root finding routine and then returns the solution. The vectorize functions works perfectly because all of the arguments and the returned result are all the same dimension. The problem is, the solution doesn't always converge. I'd like to return a True/False array that tells me whether the solution has converged or not.
I realize this can be achieved with guvectorize, but the scalar syntax of vectorize is nice, and since all of my arrays are the same dimension, it seems silly to need to bring in guvectorize. Does anyone know if its possible to return 2 or more arrays from a numba.vectorize compiled function?
The quick answer is of course... No.
From the numba docs:
While numba.vectorize() will produce a simple ufunc whose core
functionality (the function you are decorating) operates on scalar
operands and returns a scalar value...
However, if the interest is in creating a compiled function that will handle computations in a vectorized manner but return multiple values, this is still possible with guvectorize. In the below example, a function signature is defined with only one dimension in the signature, but it will happily operate on the entire array if it is multidimensional.
I know I said in the question, "I know I can do this with guvectorize" but I did not actually understand this fact that the function would work on an array of unspecified dimensions, essentially as a flattened array. I thought you needed to specify the dimensions exactly, and I haven't yet seen this behavior documented (though it might be).
from numba import guvectorize, float64
import numpy as np
ones = np.ones((3, 3))
twos = ones * 2
#guvectorize(
[(float64[:], float64[:], float64[:], float64[:])],
"(n),(n)->(n),(n)",
nopython=True)
def add_guvectorize(a, b, c, d):
for i in range(len(a)):
c[i] = a[i] + b[i]
d[i] = a[i] + c[i]
threes, fours = add_guvectorize(ones, twos)
print(threes)
print(fours)
prints:
[[3. 3. 3.]
[3. 3. 3.]
[3. 3. 3.]]
[[4. 4. 4.]
[4. 4. 4.]
[4. 4. 4.]]

including a negative number in the log sum of exponents, in python

I want to use numpy's logsumexp() in python 2.7.
The formula I need to solve looks like this:
log ( 1 + e^a1 + e^a2 + e^a3 + ... e^an - e^ax )
The last term which is a negative number just has to be appended on.
Excluding this last term, I would do the following:
myarray = numpy.array([0, a1, a2, a3, ..., an])
That way, with the first element being 0, then e^0 = 1 and so I have my first term, which is 1. Then I would just use
result = numpy.logsumexp(myarray)
and I would get the correct result.
But now I have to append a -e^ax, and because it's negative, I can't simply append ax to the end of myarray. I also can't append -ax because that's just wrong, it would mean that I'm adding 1/e^ax, instead of -e^ax.
Is there any direct way to append this so that I can still use logsumexp()? The only reason I'm insisting on using logsumexp() rather than separately using numpy.exp() and numpy.sum() and numpy.log() is because I have the impression that logsumexp also incorporates stability within it in order to prevent underflows (correct me if I'm wrong). However if there's no other way around then I guess I have no choice.
According to scipy.misc.logsumexp documentation:
scipy.misc.logsumexp(a, axis=None, b=None)
Parameters:
b: array-like, optional
Scaling factor for exp(a).
Must be of the same shape as a or broadcastable to a.
New in version 0.12.0.
So, you could add list of factors like this:
In [2]: a = [0, 1, 3, 2]
In [3]: logsumexp(a, b=[1] * (len(a) - 1) + [-1])
Out[3]: 2.7981810916785101

numpy: concise conditional syntax for array division

Assume a simple 1-dimensional numpy array:
>>> x = np.array([1,3,5,0,3,2])
Now assume I want to perform the operation 1.0/x. I can do this with numpy:
>>> 1.0/x
array([ 1. , 0.33333333, 0.2 , inf, 0.33333333,
0.5 ])
The problem here is the infinity (inf) result for the original element value 0, because 1.0/0 seems to return infinity in place of undefined behaviour.
Instead of infinity, I would like to provide my own custom value where these divide by 0 scenarios arise. While I know this can be accomplished using a loop, I would like to know whether there is any kind of idiomatic syntax for this kind of operation.
There's a related question here, but it only deals with the if something: (do this) else: (do nothing) scenario whereas my question is a if something: (do this) else: (do that) scenario.
You can always patch it up later:
a = 1.0/x
inf_ind = np.isinf(a)
a[inf_ind] = your_value
or
a[inf_ind] = f(x[inf_ind])
Which has the advantage of not getting in the way of the nice optimized numpy methods.
Building on the previous answer, you can also set floating point callback modes to detect when you need to apply the inf transform.
I can't find a callback that gets called on each floating point error, however.
See also:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.seterr.html
import numpy
class IsDivideError(object):
def __init__(self):
self.hasDivideError=False
def callback(self, x,y):
self.hasDivideError=True
ide=IsDivideError()
numpy.seterr(divide='call')
numpy.seterrcall(lambda x,y: ide.callback(x,y) )
x = numpy.array([1,3,5,0,3,2])
val=1.0/x
if(ide.hasDivideError):
val[numpy.isinf(val)]=5

Categories

Resources