简体   繁体   中英

Python: Can't convert float NaN to integer

I apply a moving average logic that returns float. I convert that float to int before using it to drawing line in OpenCV but getting below error

ValueError: cannot convert float NaN to integer

sample code

def movingAverage(avg, new_sample, N=20):
    if (avg == 0):
    return new_sample
    avg -= avg / N;
    avg += new_sample / N;
    return avg;

x1 = int(avgx1) #avgx1 is returned from the movingaverage function
y1 = int(avgy1) 
x2 = int(avgx2)
y2 = int(avgy2)
cv2.line(img, (x1, y1), (x2, y2), [255,255,255], 12)

Any suggestion on how to solve it?

Based on what you have posted, your movingAverage() function is returning NaN at some point.

NaN is a special floating point sentinel value, meaning "Not a Number." In general, Python prefers raising an exception to returning NaN , so things like sqrt(-1) and log(0.0) will generally raise instead of returning NaN . However, you may get this value back from some other library. A good example might be trying to extract a numeric value from a string cell in a spreadsheet.

Standard Python provides math.isnan(x) which you can use to test for NaN . You could either assert against it, raising an exception when it is found, or you could provide a replacement value for the NaN .

You appear to be drawing a chart or graph. My suggestion would be to specifically try to identify this problem (why are you getting this particular NaN ), and then write some code to provide a replacement.

For example, you might determine that column headers in a spreadsheet were responsible for this particular instance of NaN , and fix the code to skip over the column headers. But then, to prevent a later recurrence, you could check for isnan() in the movingAverage() function, and replace any values with either 0, or the maximum value, effectively treating NaN as 0 or infinity, whichever makes more sense to your graph.

It seems that your movingAverage() function returns NaN values.

Try

import numpy
int(numpy.nan)

Will give you

ValueError: cannot convert float NaN to integer

To test for NaN

import math, numpy
math.isnan(numpy.nan) 

you can also use:

    import numpy
    if numpy.isnan(value):
        value = numpy.nan_to_num(value)

which will change the NaN value to (probably 0.0) which can then be converted into an integer. I'd probably check to make sure that it becoming 0 works for your data.

This is my solution to this problem for loading a pandas dataframe into an oracle dbms.

{c:VARCHAR2(df[c].str.len().max()) if df[c].str.len().max() + 4 is not np.nan else VARCHAR2(4) 
     for c in df.columns[df.dtypes == 'object'].tolist()}

The key here is x is not np.nan else VARCHAR2(4) in the dict comprehension. If you are not familiar with dict comps, read that as value x if not np.nan else other value or if np.nan then x else other value

this returns a dictionary that can be used to set the dtype to load values into oracle with 4 bytes to spare. Why 4? Why not?

As @mdh pointed out, you can't convert the np.nan value to an integer. A solution would be the use of a try and except statement to catch this particular case (but you should make sure, you know, why the functions returns nan's):

try:
    x1 = int(avgx1) #avgx1 is returned from the movingaverage function
except ValueError:
    # if ValueError is raised, assign 0 to avgx1
    x1 = 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM