Vous êtes juste de voir les effets de l'arithmétique en virgule flottante. (La même chose est vraie si vous avez utilisé une liste python au lieu d'un tableau numpy.)
Je suis plutôt surpris qu'il n'y ait pas de fonction intégrée pour faire des comparaisons de "virgule flottante" en numpy ... Il y a numpy.allclose
qui le fait pour comparer entre deux tableaux numpy, mais il renvoie simplement True
ou False
plutôt qu'un tableau booléen.
Faire ceci en général est un peu compliqué. inf
sera jeté dans les faux positifs et les faux négatifs. En outre soustraction de deux tableaux avec inf
ou nan
en eux soulèvera un avertissement, si nous voulons généralement éviter de faire cela ...
import numpy as np
def close(a, b, rtol=1.e-5, atol=1.e-8, check_invalid=True):
"""Similar to numpy.allclose, but returns a boolean array.
See numpy.allclose for an explanation of *rtol* and *atol*."""
def within_tol(x, y, atol, rtol):
return np.less_equal(np.abs(x-y), atol + rtol * np.abs(y))
x = np.array(a, copy=False)
y = np.array(b, copy=False)
if not check_invalid:
return within_tol(x, y, atol, rtol)
xfin = np.isfinite(x)
yfin = np.isfinite(y)
if np.all(xfin) and np.all(yfin):
return within_tol(x, y, atol, rtol)
else:
# Avoid subtraction with infinite/nan values...
cond = np.zeros(np.broadcast(x, y).shape, dtype=np.bool)
mask = xfin & yfin
cond[mask] = within_tol(x[mask], y[mask], atol, rtol)
# Inf and -Inf equality...
cond[~mask] = (x[~mask] == y[~mask])
# NaN equality...
cond[np.isnan(x) & np.isnan(y)] = True
return cond
# A few quick tests...
assert np.any(close(0.300001, np.array([0.1, 0.2, 0.3, 0.4])))
x = np.array([0.1, np.nan, np.inf, -np.inf])
y = np.array([0.1000001, np.nan, np.inf, -np.inf])
assert np.all(close(x, y))
x = np.array([0.1, 0.2, np.inf])
y = np.array([0.101, np.nan, 0.2])
assert not np.all(close(x, y))
Pour ce que ça vaut, cela est un fait de vie en général avec arithmétique en virgule flottante. Ce n'est pas différent pour les listes python que pour les tableaux numpy. Fondamentalement, ne teste pas l'égalité à virgule flottante en utilisant '=='. –
Faites une recherche binaire dans B avec la somme des valeurs de B et comparez ensuite la valeur absolue de la différence de la valeur trouvée dans le B avec la somme de A. Vous aurez besoin de deux vérifier deux valeurs dans B parce que la somme pourrait être légèrement supérieur ou inférieur à la valeur désirée en B. –
FYI: https://github.com/numpy/numpy/commit/b9f0f1f8b54d0e4cf74ea5e7d80893d66585c4a1 Il y aura une fonction 'numpy.isclose()' dans '1.7'. –