如何总是在numpy中取整XX.5

时间:2018-11-08 04:13:53

标签: python numpy rounding

我读到numpy在四舍五入方面没有偏见,并且它的工作方式与其设计方式相同。那就是“如果您总是将0.5舍入到下一个最大数字,那么一堆舍入数字的平均值可能会比未舍入数字的平均值稍大:这种偏差或漂移会对某些数值算法和使它们不准确。“

不管这些信息,并假设我一直想取整,我该如何在numpy中做到呢?假设我的数组可能很大。

为简单起见,假设我拥有数组:

import numpy as np

A = [ [10, 15, 30], [25, 134, 41], [134, 413, 51]]
A = np.array(A, dtype=np.int16)

decimal = A * .1
whole = np.round(decimal)

十进制看起来像:

[[  1.    1.5   3. ]
 [  2.5  13.4   4.1]
 [ 13.4  41.3   5.1]]

整个样子:

[[  1.   2.   3.]
 [  2.  13.   4.]
 [ 13.  41.   5.]]

如您所见,将1.5舍入为2,将2.5舍入为2。我如何强制始终为XX.5取整?我知道我可以遍历数组并使用python round(),但这肯定会慢得多。想知道是否有一种方法可以使用numpy函数

3 个答案:

答案 0 :(得分:2)

import numpy as np
A = [ [1.0, 1.5, 3.0], [2.5, 13.4, 4.1], [13.4, 41.3, 5.1]]
A = np.array(A)

print(A)

def rounder(x):
    if (x-int(x) >= 0.5):
        return np.ceil(x)
    else:
        return np.floor(x)

rounder_vec = np.vectorize(rounder)
whole = rounder_vec(A)
print(whole)

或者,您也可以查看numpy.ceilnumpy.floornumpy.trunc其他舍入样式

答案 1 :(得分:1)

In [25]: def yourroundfunction(number):
    ...:     if(int(number)+0.5<=number):
    ...:         number=int(number)+1
    ...:     else:
    ...:         number=int(number)
    ...:     return number
    ...: 
    ...: 

In [26]:     
In [26]: customround=np.vectorize(yourroundfunction)

In [27]: customround(A)
Out[27]: 
array([[ 1,  2,  3],
       [ 3, 13,  4],
       [13, 41,  5]])

好吧,您可以定义一个customround函数,然后将其传递给np.vectorize,然后获得预期的输出。我之所以编写此自定义函数,是因为在round中调用ipython与在python中进行回合完全不一样

答案 2 :(得分:1)

答案几乎是np.vectorize。您可以并且应该以完全矢量化的方式执行此操作。假设对于x >= 0,您想要r = floor(x + 0.5)。如果希望负数四舍五入,则x < 0适用相同的公式。假设您一直想舍弃零。在这种情况下,您正在为ceil(x - 0.5)寻找x < 0

要在不调用np.vectorize的情况下为整个数组实现该功能,可以使用屏蔽:

def round_half_up(x):
    mask = (x >= 0)
    out = np.empty_like(x)
    out[mask] = np.floor(x[mask] + 0.5)
    out[~mask] = np.ceil(x[~mask] - 0.5)
    return out

请注意,如果沿一个方向四舍五入,则无需使用遮罩:

def round_up(x):
    return np.floor(x + 0.5)

现在,如果您想提高效率,可以摆脱所有临时数组。这将使用ufuncs的全部功能:

def round_half_up(x):
    out = x.copy()
    mask = (out >= 0)
    np.add(out, 0.5, where=mask, out=out)
    np.floor(out, where=mask, out=out)
    np.invert(mask, out=mask)
    np.subtract(out, 0.5, where=mask, out=out)
    np.ceil(out, where=mask, out=out)
    return out

并且:

def round_up(x):
    out = x + 0.5
    np.floor(out, out=out)
    return out