在numpy到最近的一步

时间:2011-10-22 11:23:42

标签: python numpy rounding

我想知道如何将numpy中的数字舍入到上限或下限阈值,这是预定义步长的函数。希望以更清晰的方式说明,如果我有数字123并且步长等于50,我需要将123舍入到最接近的150或100,在这种情况下为100.我出来的函数下面是哪个工作但我想知道是否有一种更好,更有效的方法来做到这一点。

提前致谢,

def getRoundedThresholdv1(a, MinClip):
    import numpy as np
    import math
    digits = int(math.log10(MinClip))+1
    b = np.round(a, -digits)
    if b > a:  # rounded-up
        c = b - MinClip
        UpLow = np.array((b,c))
    else:  # rounded-down
        c = b + MinClip
        UpLow = np.array((c,b))
    AbsDelta = np.abs(a - UpLow)
    return UpLow[AbsDelta.argmin()]




getRoundedThresholdv1(143, 50)

3 个答案:

答案 0 :(得分:9)

我认为您不需要numpy

def getRoundedThresholdv1(a, MinClip):
    return round(float(a) / MinClip) * MinClip

此处a是一个数字,如果您想要对此功能进行矢量化,则只需将round替换为np.round,将float(a)替换为np.array(a, dtype=float) < / p>

答案 1 :(得分:0)

请注意,Ruggero Turra 中的 round() 他的答案四舍五入到最接近的偶数。含义:

a= 0.5
round(a)

Out: 0

这可能不是您所期望的。

如果您想要“经典”舍入,可以使用此函数,它支持标量和 Numpy 数组:

import Numpy as np

def getRoundedThresholdv1(a, MinClip):
    scaled = a/MinClip
    return np.where(scaled % 1 >= 0.5, np.ceil(scaled), np.floor(scaled))*MinClip

或者,您可以使用 Numpy 的方法 digitize。它要求您定义步骤数组。 digitize 会将 ceil 您的价值转化为下一步。因此,为了以“经典”方式舍入,我们需要一个中间步骤。

你可以使用这个:

import Numpy as np
    
def getRoundedThresholdv1(a, MinClipBins):
    intermediate = (MinClipBins[1:] + MinClipBins[:-1])/2
    return MinClipBins[np.discritize(a, intermediate)]

然后你可以这样称呼它:

bins = np.array([0,  50, 100, 150])
test1 = getRoundedThresholdv1(74, bins)
test2 = getRoundedThresholdv1(125, bins)

给出:

test1 = 50
test2 = 150 

答案 2 :(得分:0)

总结:这是一个正确的方法,最上面的答案有不起作用的情况:

def round_step_size(quantity: Union[float, Decimal], step_size: Union[float, Decimal]) -> float:
"""Rounds a given quantity to a specific step size
:param quantity: required
:param step_size: required
:return: decimal
"""
precision: int = int(round(-math.log(step_size, 10), 0))
return float(round(quantity, precision))

我的声誉太低,无法对 Ruggero Turra 的最佳答案发表评论并指出问题。但是它有一些不起作用的情况,例如:

def getRoundedThresholdv1(a, MinClip):
    return round(float(a) / MinClip) * MinClip

getRoundedThresholdv1(quantity=13.200000000000001, step_size=0.0001)

无论是使用 numpy 还是标准库回合,都会立即返回 13.200000000000001。我什至没有通过对功能进行压力测试来发现这一点。它只是在生产代码中使用它时出现并吐出错误。

注意这个答案的全部功劳来自一个开源 github 存储库,它不是我发现的 here