python中向上或向下取整一半的快速方法

2024-03-28 16:17:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个复数的numpy数组,需要创建一个新的数组,其中实数部分和虚数部分取整,一半取整要么朝向零,要么朝向无穷大

关于stackoverflow,有几条建议使用decimal包,允许指定不同类型的舍入。对于复数数组x,以下代码起作用,但速度非常慢:

    rounded_array = np.array([
        float(Decimal(x.real).quantize(0, rounding=ROUND_HALF_DOWN)) + 1j * \
        float(Decimal(x.imag).quantize(0, rounding=ROUND_HALF_DOWNs)) for x in arr])

有哪些简单但快速的替代方案? 有人建议采取这种解决办法: How to always round up a XX.5 in numpy 但是,它仅适用于实际阵列,并且比下面建议的解决方案慢得多


Tags: innumpy数组floatarray建议复数decimal
2条回答

您可以round独立地计算实部和虚部,然后从中创建一个新数组:

rounded_array = np.fix(arr.real) + 1j*np.fix(arr.imag)

快速就地四舍五入:

arr = arr.view(float)
m = arr % 1. <= .5
arr[m] = np.floor(arr[m])
arr[~m] = np.ceil(arr[~m])
arr = arr.view(complex)

(用m = arr % 1. < .5四舍五入)

如果您需要一个新数组而不是就地更改现有数组,请将第一行更改为arr = arr.view(float).copy('K')

对于1000个元素的阵列,这比原始解决方案快大约100倍


根据以下评论更新负数:

m = arr % 1. == .5
arr[m] = np.trunc(arr[m])
arr[~m] = np.round(arr[~m])

时间安排

x = np.arange(-1000, 1000, .1)
arr = x + 1j * x

%%timeit
rounded_array = np.array([
        float(Decimal(x.real).quantize(0, rounding=ROUND_HALF_DOWN)) + 1j * \
        float(Decimal(x.imag).quantize(0, rounding=ROUND_HALF_DOWN)) for x in arr])
        
1.83 s ± 27.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
arr1 = arr.view(float).copy('K')
m = arr1 % 1. == .5
arr1[m] = np.trunc(arr1[m])
arr1[~m] = np.round(arr1[~m])
arr1 = arr1.view(complex)


1.78 ms ± 18.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

相关问题 更多 >