【问题标题】:Numpy rounding performanceNumpy舍入性能
【发布时间】:2016-05-19 15:32:46
【问题描述】:

我从 numpy(版本 1.10.4)看到了一些非常令人惊讶的行为。请参阅以下带有输出的代码:

import numpy as np

a = np.random.rand()
b = np.random.rand(1)[0]
print('a: ',a)
print('b:', b)
print('type(a): ', type(a))
print('type(a): ', type(b))
print('round(a):', round(a))
print('round(b):', round(b))
print('\n')

%timeit round(a)
%timeit round(b)
%timeit int(round(b))



a:  0.4991662851604657
b: 0.301059130742
type(a):  <class 'float'>
type(a):  <class 'numpy.float64'>
round(a): 0
round(b): 0.0


The slowest run took 7.49 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 232 ns per loop
The slowest run took 13.84 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.19 µs per loop
The slowest run took 6.54 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.37 µs per loop

np.random.rand 似乎在两种非常相似的情况下返回不同的数字类型。

这让我很生气,因为我开始依赖 Python 的 round 的行为,它默认返回 int。但是,如果round 的输入是numpy.float64,它会返回float,我猜是因为numpy.round 确实如此。依赖round 的行为突然变得相当危险。

roundfloatnumpy.float64 上的表现也有很大不同,以至于它对我的库产生了明显的影响。

性能问题是一个错误,还是 numpy 开销真的戏剧性,即使对于标量 floats,还是这里的基准测试工作方式存在问题?如何从numpy.float64s 快速舍入到int 性能?

最后,为什么rand() 返回的类型与rand(1)[0] 不同?

【问题讨论】:

    标签: python performance numpy types rounding


    【解决方案1】:

    round(a)实际上调用了a.__round__(),这对于pythonfloatnp.float的实现可能不同。由于应用的不同,开发者一定为__round__的每一个返回选择了不同的返回类型。

    恐怕没有可靠的通用方法将numpy 性能扩展到python 原生类型。您可以调查 numba 软件包以获取 jit 功能。

    编辑:

    关于您的最后一个问题,我的猜测是 np.rand 返回 float 作为优化以避免在您只需要一个随机数时将其装箱到 array 中。

    【讨论】:

    • 实际上,我希望将本机性能扩展到 numpy,而不是相反。我期待 numpy 优于原生 Python,因此我感到很惊讶。不过,Numba 是个好主意。有趣的是,定义我自己的简单调用round 的方法,带有@jit 装饰,恢复了性能,并且 还返回一个int,即使在numpy.float64s 上也是如此。你知道这是为什么吗?
    • 我刚刚发现了这个:stackoverflow.com/questions/27252209/… 简而言之,您可以使用np.intc 进行舍入,但要确保它的行为符合您的要求。关于numba 类型转换,我不确定,但我认为它本身就是一个很好的问题。
    • 有趣。但是,np.intc 似乎是截断而不是四舍五入。此外,它在原生 floats 上的性能只有原生 round 的一半,而在 numpy.float64s 上又慢了一倍。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多