84

I am doing some simple math recessively in a python script and am getting the follow warning:

"Warning: divide by zero encountered in divide".

To provide some context, I am taking two values and trying to find the percent difference in value (a - b) / a and if its above a certain range then process it, but sometimes the value of a or b is zero.

I want to get rid of this specific warning (at a specific line) but all the information I have found so far seems to show me how to stop all warnings (which I do not want).

When I used to write shell scripts, I could do something like this

code...
more code 2 > error.txt
even more code  

In that example, I would get the warnings for the 'code' and 'even more code' command but not for the second line.

Is this possible?

tmthydvnprt
  • 10,398
  • 8
  • 52
  • 72
Lostsoul
  • 25,013
  • 48
  • 144
  • 239

4 Answers4

177

If Scipy is using the warnings module, then you can suppress specific warnings. Try this at the beginning of your program:

import warnings
warnings.filterwarnings("ignore", message="divide by zero encountered in divide")

If you want this to apply to only one section of code, then use the warnings context manager:

import warnings
with warnings.catch_warnings():
    warnings.filterwarnings("ignore", message="divide by zero encountered in divide")
    # .. your divide-by-zero code ..
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 15
    Nice answer. Actually it took me a surprising amount of googling to find this ultra-simple explanation of how to ignore warnings. @Lostsoul you can use message='regex matching message' to catch warnings by message, and there are also lineno= and module= arguments to catch by line number and module name. – cxrodgers Feb 07 '13 at 23:02
  • 1
    similarly if there's a category of warnings you want to suppress, replace `message=` with `category=` e.g. `category=FutureWarning` – fantabolous Jun 04 '23 at 13:13
18

I'd avoid the division-by-zero in the first place:

if a == 0:
    # Break out early

# Otherwise the ratio makes sense

If you do want to squash that particular numpy warning on a single line, numpy provides a way:

with numpy.errstate(divide='ignore'):
    # The problematic line
Blender
  • 289,723
  • 53
  • 439
  • 496
8

Blenders answer is perfectly fitting the problem. Maybe someone is interested in another general approach to catch specific warnings with either regex or the line number:

surpress a warning caused by a specific line, here line 113:

import warnings
warnings.simplefilter('ignore',lineno=113)

This approach has the disadvantage, that each time you change something in the code you need to readjust the lineno. The other option is to catch a warning using regex. The following code will return

import warnings
warnings.filterwarnings('ignore', message='.*show', )
warnings.warn('Do not do this!')
warnings.warn('Do not show this message')
>>> UserWarning: Do not do this!
        warnings.warn('Do not do this!')

The dot before the *-symbol is neccessary as otherwise an error is returned

error: nothing to repeat

which is discussed in this thread

Jakob
  • 168
  • 1
  • 6
2

For anyone who by specific warnings mean specific warning classes (categories in warning handling jargon), then you can pass the category to be suppressed to the category parameter of the simplefilter or filterwarnings function:

import warnings
warnings.simplefilter("ignore", category=Warning)
sourcream
  • 210
  • 1
  • 11