Básicamente quiero comparar una variable entre dos np.arange()
x = 22.03 first = np.arange(18.5, 24.99, 0.01) second = np.arange(25.0, 29.99, 0.01) if x in first: print("x is in first") elif x in second: print("x is in second") Espero ver "x isin first" pero no obtengo nada impreso en la terminal. Si agrego otro else: declaración, ejecutará lo que sea que esté en eso.
Estoy usando numpy porque quiero tener un rango de flotadores. La función range() no admite flotantes
No pasa nada de comparación entre los dos, ¿por qué?
Su matriz:
In [254]: first = np.arange(18.5, 24.99, 0.01) In [255]: first.shape Out[255]: (649,) In [256]: first[:10] Out[256]: array([18.5 , 18.51, 18.52, 18.53, 18.54, 18.55, 18.56, 18.57, 18.58, 18.59]) In [257]: x=22.03 x no se "encuentra"
In [258]: x in first Out[258]: FalseBusquemos una coincidencia cercana:
In [259]: np.nonzero(np.isclose(x,first)) Out[259]: (array([353]),) In [260]: first[353] Out[260]: 22.030000000000552La coincidencia más cercana todavía está un poco apagada, debido a los cálculos de punto flotante. Las pruebas 'en/iguales' en valores de punto flotante no son confiables.
arange recomienda linspace cuando se usan pasos flotantes. Los valores resultantes se acercan más a nuestras expectativas:
In [264]: first1 = np.linspace(18.5,24.98,len(first)) In [265]: np.nonzero(np.isclose(x,first1)) Out[265]: (array([353]),) In [266]: first1[353] Out[266]: 22.03 In [267]: x in first1 Out[267]: TrueTodavía existe la posibilidad de un desajuste de flotación.
Para ver mejor la precisión total de los flotadores, mostremos las matrices como listas
In [268]: first[:10].tolist() Out[268]: [18.5, 18.51, 18.520000000000003, 18.530000000000005, 18.540000000000006, 18.550000000000008, 18.56000000000001, 18.57000000000001, 18.580000000000013, 18.590000000000014] In [269]: first1[:10].tolist() Out[269]: [18.5, 18.51, 18.52, 18.53, 18.54, 18.55, 18.56, 18.57, 18.58, 18.59]x = 22.03 first = np.arange(18.5, 24.99, 0.01) second = np.arange(25.0, 29.99, 0.01) type(first) Out[13]: numpy.ndarray # cast to list and proper value rounding for boolean comparison first = [round(n, 2) for n in first] x in first Out[16]: True