Reputation: 967
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
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
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