在 python 中向上或向下舍入一半的快速方法
Fast method to round half up or down in python
我有一个 numpy 复数数组,需要创建一个包含四舍五入的实部和虚部的新数组,其中四舍五入是向零或向无穷大。
在 Whosebug 上有一些关于使用 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])
有哪些简单但更快的替代方法?
建议使用此解决方案:
但是,它仅适用于真实数组,并且比下面建议的解决方案慢得多。
您可以 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 倍。
UPDATE 根据以下评论对负数进行更新:
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)
我有一个 numpy 复数数组,需要创建一个包含四舍五入的实部和虚部的新数组,其中四舍五入是向零或向无穷大。
在 Whosebug 上有一些关于使用 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])
有哪些简单但更快的替代方法?
建议使用此解决方案:
您可以 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 倍。
UPDATE 根据以下评论对负数进行更新:
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)