Подсчет вхождений поплавков в массиве поплавков

#python-3.x #list #numpy #count

Вопрос:

Допустим, у меня есть список ключей, которые есть floats .

keys = [0.999999, 1.999999]

Допустим, у меня есть другой список ценностей.

vals = [1.0, 2.0, 3.0, 4.0, 5.0, 1.0, 1.0, 2.0]

Я хочу найти общее количество раз, когда каждое key из них происходит, vals и я измеряю равенство с помощью np.isclose() . В приведенном выше примере ответ будет 5. Следующий фрагмент может вернуть этот ответ, но он очень медленный , когда keys и vals больше по размеру ( 10^6 и 10^7 соответственно).

 def count_float_keys(keys,vals):
    count = 0
    for key in keys:
        present = np.where(np.isclose(vals,key))[0]
        count  = len(present)
    return count
 

Есть ли более быстрая и чистая альтернатива для этого?

Изменить: 0.99999 используется только в качестве упрощающего примера. Мои данные имеют случайные значения с плавающей точкой, подобные 0.035014 тем, которые мне не разрешается округлять дальше.

Ответ №1:

Вот, пожалуйста:

 # generate random vals
vals = np.random.randint(0,2,(10,10))   np.random.uniform(0,1,(10,10))
keys = [0.999999, 1.999999]
# check how often each value is in the tolerance of each key
res = [np.sum(np.isclose(vals,k, rtol=0.1, atol=0.1)) for k in keys]
 

Комментарии:

1. Мне не разрешается заходить keys или vals заходить дальше. Я обновил этот вопрос следующим образом.

2. Я отредактировал свой ответ

3. Это быстрее , так как вы пропускаете np.where и используете напрямую np.sum , верно? Знаете ли вы, есть ли способ векторизации внутреннего for цикла keys ? Насколько я понимаю, np.all_close() это не позволяет транслировать.

4. Я не знаю никакой альтернативы перебору ключей с использованием какой-либо векторизации.