Я только что заметил, что принятый ответ не работает.Например, в этом случае:
a = 1-np.random.random(20)*0.05
<20 uniformly chosen values between 0.95 and 1.0>
np.sort(a)
>>>> array([ 0.9514548 , 0.95172218, 0.95454535, 0.95482343, 0.95599525,
0.95997008, 0.96385762, 0.96679186, 0.96873524, 0.97016127,
0.97377579, 0.98407259, 0.98490461, 0.98964753, 0.9896733 ,
0.99199411, 0.99261766, 0.99317258, 0.99420183, 0.99730928])
TOL = 0.01
В результате получается:
a.flat[i[d>TOL]]
>>>> array([], dtype=float64)
Просто потому, что ни одно из значений отсортированного входного массива не достаточно разнесено, чтобы быть как минимум «TOL», в то время какправильный результат должен быть:
>>>> array([ 0.9514548, 0.96385762, 0.97016127, 0.98407259,
0.99199411])
(хотя это зависит от того, как вы решаете, какое значение взять в пределах «TOL»)
Следует использовать тот факт, что целые числа не страдают от такихЭффект точности станка:
np.unique(np.floor(a/TOL).astype(int))*TOL
>>>> array([ 0.95, 0.96, 0.97, 0.98, 0.99])
, который работает в 5 раз быстрее, чем предлагаемое решение (согласно% timeit).
Обратите внимание, что «.astype (int)» является необязательным, хотя его и удаляютухудшает производительность в 1,5 раза, учитывая, что извлечение уникальных значений из массива int выполняется намного быстрее.
Возможно, вы захотите добавить половину «TOL» к результатам уникальных операций, чтобы компенсировать настилэффект:
(np.unique(np.floor(a/TOL).astype(int))+0.5)*TOL
>>>> array([ 0.955, 0.965, 0.975, 0.985, 0.995])