muammar
muammar

Reputation: 967

Replace values in numpy arrays not working

I have the following problem, and I'd be glad if somebody could explain to me why this is happening.

So, I have this numpy array:

[[ 0.          2.68530063  2.68530063  4.65107712  4.65107712  5.37060126
   2.68530063  4.65107712  4.65107712  5.37060126]
 [ 2.68530063  0.          4.65107712  2.68530063  5.37060126  4.65107712
   4.65107712  2.68530063  5.37060126  4.65107712]
 [ 2.68530063  4.65107712  0.          5.37060126  2.68530063  4.65107713
   4.65107712  7.10463766  7.10463766  8.05590189]
 [ 4.65107712  2.68530063  5.37060126  0.          4.65107713  2.68530063
   7.10463766  4.65107712  8.05590189  7.10463766]
 [ 4.65107712  5.37060126  2.68530063  4.65107713  0.          2.68530063
   7.10463766  8.05590189  9.30215425  9.68198911]
 [ 5.37060126  4.65107712  4.65107713  2.68530063  2.68530063  0.
   8.05590189  7.10463766  9.68198911  9.30215425]
 [ 2.68530063  4.65107712  4.65107712  7.10463766  7.10463766  8.05590189
   0.          5.37060126  2.68530063  4.65107713]
 [ 4.65107712  2.68530063  7.10463766  4.65107712  8.05590189  7.10463766
   5.37060126  0.          4.65107713  2.68530063]
 [ 4.65107712  5.37060126  7.10463766  8.05590189  9.30215425  9.68198911
   2.68530063  4.65107713  0.          2.68530063]
 [ 5.37060126  4.65107712  8.05590189  7.10463766  9.68198911  9.30215425
   4.65107713  2.68530063  2.68530063  0.        ]]

And I want to perform replacements as follows: a) values in array == 0, I want them to be 1. b) values in array == 2.68530063, I want them to be -1, and c) values > 2.68530063 I want them to be 0.

I found that a very compact a nice way of doing it would be this one:

distances[distances==0.00000000]  = 1
distances[distances > 2.68530063] = 0
distances[distances==2.68530063]  = -1

However, my new array output is this:

[[ 1.         -1.          2.68530063  0.          0.          0.
   2.68530063  0.          0.          0.        ]
 [-1.          1.          0.          2.68530063  0.          0.          0.
   2.68530063  0.          0.        ]
 [ 2.68530063  0.          1.          0.          0.          0.          0.
   0.          0.          0.        ]
 [ 0.          2.68530063  0.          1.          0.          0.          0.
   0.          0.          0.        ]
 [ 0.          0.          0.          0.          1.         -1.          0.
   0.          0.          0.        ]
 [ 0.          0.          0.          0.         -1.          1.          0.
   0.          0.          0.        ]
 [ 2.68530063  0.          0.          0.          0.          0.          1.
   0.          0.          0.        ]
 [ 0.          2.68530063  0.          0.          0.          0.          0.
   1.          0.          0.        ]
 [ 0.          0.          0.          0.          0.          0.          0.
   0.          1.         -1.        ]
 [ 0.          0.          0.          0.          0.          0.          0.
   0.         -1.          1.        ]]

My very big doubt here is: why some values == 2.68530063 remains in my numpy array? I really don't get why given that the condition I imposed should be for all values == 2.68530063 (just as it works correctly for the other conditions). And second, what would be then a way of replace correctly a numpy array. I'd like to thank you very much in advance, and happy new year 2014.

Upvotes: 0

Views: 623

Answers (2)

ssm
ssm

Reputation: 5373

Did you try:

distances[distances == 0]  = 1
distances[distances > 2.685300635] = 0
distances[distances > 2.685300625 and distances < 2.685300635]          = -1

?

I have seen this behavior before when trying to use specific values. Basically, 2.68530063 may not be exactly equal to 2.68530063 in memory. It is an approximation to the nearest value represented by the specified number of decimal places ...

Edit: The last check should be:

distances[(distances > 2.685300625) * (distances < 2.685300635)] = -1

I think that last one should work ...

Upvotes: 0

user2357112
user2357112

Reputation: 280778

The array elements that display as 2.68530063 may not be exactly equal to 2.68530063. NumPy truncates array elements for display purposes, and rounding error in the computations that produced your array may have caused elements to have values slightly off from what you'd expect. You can use numpy.isclose to perform comparisons within a tolerance:

distances[numpy.isclose(distances, 0)]  = 1
distances[distances > 2.68530063] = 0
distances[numpy.isclose(distances, 2.68530063)]  = -1

Also, note that the order you perform these assignments in is important. When you compare distances > 2.68530063, the distances values that used to equal 0 will now be 1. That might cause bugs if you're not careful.

Upvotes: 3

Related Questions