Самый быстрый способ обнулить низкие значения в массиве?

попробуйте использовать это

set_status_header(404);
34
задан mskfisher 15 June 2012 в 13:37
поделиться

8 ответов

​​

Это типичная задача для NumPy , которая очень быстрая для таких операций:

array_np = numpy.asarray(array)
low_values_flags = array_np < lowValY  # Where values are low
array_np[low_values_flags] = 0  # All low values set to 0

Теперь, если вам нужны только самые большие элементы highCountX, вы можете даже «забыть» о мелких элементах (вместо того, чтобы устанавливать для них значение 0 и сортировать их) и сортировать только список больших элементов:

array_np = numpy.asarray(array)
print numpy.sort(array_np[array_np >= lowValY])[-highCountX:]

Конечно, сортировка всего массива, если вам нужно всего несколько элементов, может быть неоптимальной. В зависимости от ваших потребностей вы можете рассмотреть стандартный модуль heapq .

76
ответ дан 27 November 2019 в 16:02
поделиться

Использование numpy :

# assign zero to all elements less than or equal to `lowValY`
a[a<=lowValY] = 0 
# find n-th largest element in the array (where n=highCountX)
x = partial_sort(a, highCountX, reverse=True)[:highCountX][-1]
# 
a[a<x] = 0 #NOTE: it might leave more than highCountX non-zero elements
           # . if there are duplicates

Где partial_sort может быть:

def partial_sort(a, n, reverse=False):
    #NOTE: in general it should return full list but in your case this will do
    return sorted(a, reverse=reverse)[:n] 

Выражение a [a <значение] = 0 можно записать без numpy следующим образом:

for i, x in enumerate(a):
    if x < value:
       a[i] = 0
6
ответ дан 27 November 2019 в 16:02
поделиться

Самый простой способ:

topX = sorted([x for x in array if x > lowValY], reverse=True)[highCountX-1]
print [x if x >= topX else 0 for x in array]

По частям выбираются все элементы больше, чем lowValY :

[x for x in array if x > lowValY]

Этот массив содержит только количество элементов больше, чем порог. Затем отсортируем его так, чтобы в начале были наибольшие значения:

sorted(..., reverse=True)

Затем индекс списка принимает порог для верхних highCountX элементов:

sorted(...)[highCountX-1]

Наконец, исходный массив заполняется с использованием другого понимания списка :

[x if x >= topX else 0 for x in array]

Существует граничное условие, когда есть два или более равных элемента, которые (в вашем примере) являются третьими по величине элементами. Результирующий массив будет содержать этот элемент более одного раза.

Есть и другие граничные условия, например, if len (array) . Обработка таких условий оставлена ​​на усмотрение разработчика.

5
ответ дан 27 November 2019 в 16:02
поделиться

Установить элементы ниже некоторого порога до нуля очень просто:

array = [ x if x > threshold else 0.0 for x in array ]

(плюс иногда abs (), если необходимо.)

Однако требование N самых высоких чисел немного расплывчато. Что, если, например, имеется N + 1 равное число выше порога? Какой из них усечь?

Вы можете сначала отсортировать массив, а затем установить порог равным значению N-го элемента:

threshold = sorted(array, reverse=True)[N]
array = [ x if x >= threshold else 0.0 for x in array ]

Примечание: это решение оптимизировано для удобочитаемости, а не производительности.

2
ответ дан 27 November 2019 в 16:02
поделиться

Вы можете использовать map и lambda, это должно быть достаточно быстро.

new_array = map(lambda x: x if x>y else 0, array)
1
ответ дан 27 November 2019 в 16:02
поделиться

Используйте кучу .

0
ответ дан 27 November 2019 в 16:02
поделиться

Использование кучи - хорошая идея, как говорит Эгон. Но вы можете использовать функцию heapq.nlargest , чтобы сократить некоторые усилия:

import heapq 

array =  [.06, .25, 0, .15, .5, 0, 0, 0.04, 0, 0]
highCountX = 3
lowValY = .1

threshold = max(heapq.nlargest(highCountX, array)[-1], lowValY)
array = [x if x >= threshold else 0 for x in array]
0
ответ дан 27 November 2019 в 16:02
поделиться

В NumPy есть специальный класс MaskedArray, который делает именно это. Вы можете «замаскировать» элементы на основе любого предварительного условия. Это лучше отражает вашу потребность, чем присвоение нулей: операции numpy будут игнорировать маскированные значения, когда это необходимо (например, поиск среднего значения).

>>> from numpy import ma
>>> x = ma.array([.06, .25, 0, .15, .5, 0, 0, 0.04, 0, 0])
>>> x1 = ma.masked_inside(0, 0.1) # mask everything in 0..0.1 range
>>> x1
masked_array(data = [-- 0.25 -- 0.15 0.5 -- -- -- -- --],
         mask = [ True False True False False True True True True True],
   fill_value = 1e+20)
>>> print x.filled(0) # Fill with zeroes
[ 0 0.25 0 0.15 0.5 0 0 0 0 0 ]

В качестве дополнительного преимущества, маскированные массивы хорошо поддерживаются в библиотеке визуализации matplotlib, если вам это нужно.

Документы по маскированным массивам в numpy

7
ответ дан 27 November 2019 в 16:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: