Python 将数组中的低值归零的最快方法?

Python 将数组中的低值归零的最快方法?,python,arrays,floating-point,max,min,Python,Arrays,Floating Point,Max,Min,假设我有100000个浮点数组,每个数组有100个元素。我需要最大数量的X值,但前提是它们大于Y。任何不匹配的元素都应设置为0。在Python中,最快的方法是什么?必须维持秩序。大多数元素已设置为0 样本变量: array = [.06, .25, 0, .15, .5, 0, 0, 0.04, 0, 0] highCountX = 3 lowValY = .1 预期结果: array = [0, .25, 0, .15, .5, 0, 0, 0, 0, 0] 最简单的方法是: topX =

假设我有100000个浮点数组,每个数组有100个元素。我需要最大数量的X值,但前提是它们大于Y。任何不匹配的元素都应设置为0。在Python中,最快的方法是什么?必须维持秩序。大多数元素已设置为0

样本变量:

array = [.06, .25, 0, .15, .5, 0, 0, 0.04, 0, 0]
highCountX = 3
lowValY = .1
预期结果:

array = [0, .25, 0, .15, .5, 0, 0, 0, 0, 0]

最简单的方法是:

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]
array_np = numpy.asarray(array)
print numpy.sort(array_np[array_np >= lowValY])[-highCountX:]
最后,使用另一个列表填充原始数组:

[x if x >= topX else 0 for x in array]
有一个边界条件,其中有两个或多个相等的元素(在您的示例中)是第三高的元素。结果数组将多次包含该元素

还有其他边界条件,例如if
len(array)
。处理此类条件由实施者来完成。

这是一项典型的工作,对于此类操作来说,这是一项非常快速的工作:

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

当然,如果只需要几个元素,对整个数组进行排序可能不是最优的。根据您的需要,您可能需要考虑标准模块。

< P>低于某个阈值的设置元素是容易的:

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 ]

注意:此解决方案针对可读性而非性能进行了优化。

使用
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

表达式
a[a您可以使用map和lambda,它应该足够快

new_array = map(lambda x: x if x>y else 0, array)
使用一个

这在时间
O(n*lg(HighCountX))
中起作用


deletemin在heap
O(lg(k))
和insertion
O(lg(k))
O(1)
中工作,具体取决于您使用的堆类型。

NumPy中有一个特殊的MaskedArray类,可以实现这一点。您可以“屏蔽”基于任何先决条件的元素。这比指定零更好地代表您的需要:numpy操作将在适当时忽略屏蔽值(例如,查找平均值)

此外,如果您需要,matplotlib可视化库很好地支持掩码数组


正如埃贡所说,使用堆是一个好主意。但是您可以使用
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]

:)

如果x>lowValY,您可以使用数组中的x代表x,而不是[x代表数组中的x,如果x>lowValY],只对原始数组进行枚举而不复制它(如果原始数据非常大,这可能是一件好事)。这是正确的。
sorted()
无论如何都可能需要整个列表。嘿,比我的noob代码快3倍,但我需要相等的元素来保持highCountX限制。数组应该有20-200个元素……它们实际上是一个更大数组的片段,我可以分块处理。感谢到目前为止的帮助。我看不出你是如何处理的
zero
ing原始数组中的元素。如果
highCountX>len([x表示数组中的x,如果x>lowValY])
那么您将得到indexer。highCountX是我希望在数组中存在的非零元素的最大数量。如果是2,则预期结果将是:[0,0,0,.15,.5,0,0,0,0,0,0]-highCountX限制结果中非零元素的数量。如果值的数量超过highCountX,如何选择要保留的元素和要丢弃的元素highCountX保留最高值…如果存在重复值,则选择哪一个并不重要used@David你应该考虑确认其中一个反应,以便告诉读者THA。它真的解决了你的问题!很好…使用合适的库可以让你走得更远:-)我一直遇到这个小家伙,我想我必须去看看:)谢谢你的帮助(每个人)@David NumPy确实满足了您的需求。我建议您从我链接的教程开始:这可能是了解NumPy并学习其最重要概念的最快方法。什么更快:
array\u np[低值\u索引]=0
数组\u np*=低值\u索引
?假设您将numpy作为np导入…那么您也可以使用index=np。其中(数组阈值
,则最终数组中的非零元素太多)。从scipy 0.17.1起已弃用,请参阅
new_array = map(lambda x: x if x>y else 0, array)
import heapq

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

for i in range(1,highCountX):
    heappush(heap, lowValY)
    heappop(heap)

for i in range( 0, len(array) - 1)
    if array[i] > heap[0]:
        heappush(heap, array[i])

min = heap[0]

array = [x if x >= min else 0 for x in array]
>>> 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 ]
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]
from scipy.stats import threshold
thresholded = threshold(array, 0.5)