在 numpy 中舍入到最近的步骤

问题描述 投票:0回答:3

我想知道如何将 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)
python numpy rounding
3个回答
20
投票

pb360 的解决方案要好得多,使用 python3 中内置 round 的第二个参数。

我认为你不需要

numpy
:

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

这里

a
是单个数字,如果你想向量化这个函数,你只需要将
round
替换为
np.round
,将
float(a)
替换为
np.array(a, dtype=float)


8
投票

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

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 存储库,这不是我发现的这里


2
投票

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

round()

这可能不是你所期望的。

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

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

。它要求您定义步骤数组。

digitize
将会
digitize
您对下一步的价值。因此,为了以“经典”方式进行舍入,我们需要一个中间步骤。
您可以使用这个:

ceil

然后你可以这样称呼它:

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

这给出了:

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

© www.soinside.com 2019 - 2024. All rights reserved.