85801

numpy.reciprocal returns different values when called repeatedly [duplicate]

Question:

This question already has an answer here:

<ul><li> <a href="/questions/45543505/what-is-the-default-of-numpy-functions-with-where-false" dir="ltr" rel="nofollow">What is the default of numpy functions, with where=False?</a> <span class="question-originals-answer-count"> 1 answer </span> </li> </ul>

I have a numpy array ssh_sum:

>>> ssh_sum array([[ 0., 2., 1., 0., 0., 0.], [ 0., 0., 1., 2., 0., 0.], [ 0., 0., 0., 1., 0., 2.]])

I wanted to compute the element-wise reciprocal values in this array. Numpy returns different values when I call np.reciprocal repeatedly:

>>> ssh_sum array([[ 0., 2., 1., 0., 0., 0.], [ 0., 0., 1., 2., 0., 0.], [ 0., 0., 0., 1., 0., 2.]]) >>> np.reciprocal(ssh_sum, where=(ssh_sum > 0.)) array([[ 6.90326535e-310, 5.00000000e-001, 1.00000000e+000, 0.00000000e+000, 1.07034283e-296, 1.33666925e+241], [ 4.74783847e-309, 1.45260789e-296, 1.00000000e+000, 5.00000000e-001, 2.13436228e-287, -3.13188338e-294], [ 4.85105226e-309, 1.08690709e+171, 4.09521901e+149, 1.00000000e+000, 2.82730247e-311, 5.00000000e-001]]) >>> np.reciprocal(ssh_sum, where=(ssh_sum > 0.)) array([[ inf, 0.5, 1. , inf, inf, inf], [ inf, inf, 1. , 0.5, inf, inf], [ inf, inf, inf, 1. , inf, 0.5]]) >>> np.reciprocal(ssh_sum, where=(ssh_sum > 0.)) array([[ 6.90326535e-310, 5.00000000e-001, 1.00000000e+000, 0.00000000e+000, 1.07034283e-296, 1.33666925e+241], [ 4.74783847e-309, 1.45260789e-296, 1.00000000e+000, 5.00000000e-001, 2.13436228e-287, -3.13188338e-294], [ 4.85105226e-309, 1.08690709e+171, 4.09521901e+149, 1.00000000e+000, 2.82730247e-311, 5.00000000e-001]]) >>> np.reciprocal(ssh_sum, where=(ssh_sum > 0.)) array([[ inf, 0.5, 1. , inf, inf, inf], [ inf, inf, 1. , 0.5, inf, inf], [ inf, inf, inf, 1. , inf, 0.5]])

Any idea what's going on here? I'm using Python 3.4.5 and numpy 1.13.3.

Answer1:

It is not just reciprocal; the issue occurs with any use of the where argument. I've been able to reproduce the issue with the master branch of numpy (np.__version__ is '1.15.0.dev0+c093997'), with functions such as abs, sign, add, subtract, etc.

If you read the docstrings of the numpy "ufuncs" carefully and interpret them correctly, you'll see that the behavior is not a bug. Here are the relevant descriptions from the numpy.reciprocal docstring:

out : ndarray, None, or tuple of ndarray and None, optional A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or `None`, a freshly-allocated array is returned. A tuple (possible only as a keyword argument) must have length equal to the number of outputs. where : array_like, optional Values of True indicate to calculate the ufunc at that position, values of False indicate to leave the value in the output alone.

Note, in particular:

<ul><li>where says "values of False indicate to leave the value in the output alone."</li> <li>out says "If not provided or None, a freshly-allocated array is returned."</li> </ul>

You did not provide an out argument, so a new array is allocated by your call to reciprocal. The contents of this array are not initialized; the array holds whatever happened to be in the allocated memory. When you use the where argument, only those positions in the output where where is True are assigned values. Positions where where is False are not touched, so they hold whatever random stuff was there when the array was allocated. For floating point output, the random stuff in the output might be 0.0, 4.85105226e-309, or any other random values.

To use the where argument the way you intended, you should also provide your own out argument, initialized with the values you want in the output where where is False. In your case, you should pass in an array of zeros:

In [84]: ssh_sum Out[84]: array([[0., 2., 1., 0., 0., 0.], [0., 0., 1., 2., 0., 0.], [0., 0., 0., 1., 0., 2.]]) In [85]: out = np.zeros_like(ssh_sum) In [86]: np.reciprocal(ssh_sum, where=ssh_sum > 0.0, out=out) Out[86]: array([[0. , 0.5, 1. , 0. , 0. , 0. ], [0. , 0. , 1. , 0.5, 0. , 0. ], [0. , 0. , 0. , 1. , 0. , 0.5]]) In [87]: out Out[87]: array([[0. , 0.5, 1. , 0. , 0. , 0. ], [0. , 0. , 1. , 0.5, 0. , 0. ], [0. , 0. , 0. , 1. , 0. , 0.5]])

Recommend

  • Jenkins Declarative pipeline get build failure cause
  • Apyori relevance measure
  • Replace nth match of matches with regex
  • How datetime values are stored in mysql?
  • Use iframe within phonegap developer app
  • Can't access docker url via curl or Postman
  • StringBuilder and capacity?
  • Hibernate : How to prevent SQL injection when the collection elements needs to check with `like` ope
  • PostgreSQL: concatenate nested arrays with differing element dimensions
  • php cron job execute javascript as well
  • Spring 4 recommended replacement of JpaTemplate
  • generatesDecimalNumbers for NumberFormatter does not work
  • Run As JUnit not appearing in Eclipse - using JUnit4
  • Okhttp3 set timeout is useless
  • Unable to mock URL class using PowerMockito/Mockito
  • runif function in Cuda
  • Python - Checking every item in a list against every other item efficiently
  • How to make Expiring/Signed video embed urls
  • Can't install profiler symfony flex
  • CLIENT STACK TRACE in Hibernate using c3p0
  • How does Node keep a server process alive?
  • How to add a CAGradientLayer to a UIView when using programmatic constraints
  • Rails Template Error with Heroku
  • Reading large text file very slow
  • How to get a Builder object from rows related to pivot - Laravel
  • Debug Azure Functions locally
  • Zip library for Windows Phone 7
  • Existing data serialized as hash produces error when upgrading to Rails 5
  • JSF validateLength question
  • Coin change recursive approach
  • How to HTTP POST a Blob to a different domain? [duplicate]
  • using vtkTimerCallback with QVTKRenderWindowInteractor not working
  • Using django-multiupload within a ModelForm
  • Bison does not appear to recognize C string literals appropriately
  • Facebook friend list in Facebook Android SDK 3.14
  • Multiple canvases (pages) in Fabric.js
  • Pick Out Specific Number from Array? [duplicate]
  • How to call jQuery function in HTML returned by AJAX