【发布时间】:2018-03-16 07:26:13
【问题描述】:
numpy.trunc是一个基于abs值的下限函数:
a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
np.floor(a)
Out[122]: array([-2., -2., -1., 0., 1., 1., 2.])
np.trunc(a)
Out[123]: array([-1., -1., -0., 0., 1., 1., 2.])
ceil 输出是这样的:
np.ceil(a)
Out[124]: array([-1., -1., -0., 1., 2., 2., 2.])
但我想要一个输出:array([-2., -2., -1., 1., 2., 2., 2.]) 这个的numpy函数是什么?
编辑: 不幸的是,没有远离零功能的内置回合。根据@Mitch 和@Divakar 的回答,我做了一些测试并尝试优化速度和内存使用。
def rawzero1(a): #@Mitch
return np.sign(a)*np.ceil(np.abs(a))
def rawzero2(a): #@Divakar
return np.where(a<0, np.floor(a), np.ceil(a))
def rawzero3(a):
_a = np.abs(a)
np.ceil(_a, _a) # inplace
np.copysign(_a, a, out = _a)
return _a
def rawzero4(a):
_a = np.ceil(np.abs(a))
np.copysign(_a, a, out = _a)
return _a
array size: 762.94 MB
| func | t per call (ms) | max mem use (MB) | mem to array size (MB) |
|:---------|------------------:|-------------------:|-------------------------:|
| rawzero1 | 1071.34 | 3082.51 | 4.04 |
| rawzero2 | 1237.74 | 3183.39 | 4.17 |
| rawzero3 | 543.71 | 1576.41 | 2.07 |
| rawzero4 | 583.83 | 2328.77 | 3.05 |
所以最好的是 rawzero3,它使用 inplace 操作来减少内存使用和 copysign 来加速。
根据需要 numexpr >=2.6.4 的 @Divakar 进行更新。之前的任何版本都没有ceil()。
rawzero1(a) == rawzero2(a)
rawzero1(a) == rawzero3(a)
rawzero1(a) == rawzero4(a)
rawzero1(a) == numexpr_1(a)
array size: 762.94 MB
| func | t per call (ms) | max mem use (MB) | mem to array size (MB) |
|:----------|------------------:|-------------------:|-------------------------:|
| rawzero1 | 1108.68 | 3828.35 | 5.02 |
| rawzero2 | 1226.78 | 3940.69 | 5.17 |
| rawzero3 | 531.54 | 2323.55 | 3.05 |
| rawzero4 | 579.55 | 3082.49 | 4.04 |
| numexpr_1 | 228.00 | 2323.57 | 3.05 |
一点也不意外。 numexpr 版本将提供最佳速度和与 rawzero3 相同的内存占用。奇怪的是 rawzero3 的内存占用有点不稳定。理论上它应该只使用 2x 数组大小而不是 3x。
【问题讨论】:
-
请注意,trunc 和 floor 都没有使用绝对值的概念。
trunc向零舍入,而floor向负无穷舍入。ceil向正无穷大舍入,因此您正在寻找从零开始舍入 远离 的东西。我不知道有一个内置函数可以做到这一点。 -
在我的帖子中添加了一种基于@Mitch 的签名想法的方法,该方法似乎比其他方法快得多。是否也将其添加到内存测试的基准测试设置中?
-
@Divakar 您使用的是哪个版本的 numexpr?我之前尝试使用 numexpr,但它不支持 ceil 功能。我很惊讶你可以让它工作。我正在使用 2.6.2
-
@Wang Yeah
ceil是最近添加的。我需要升级它。你能升级你的吗?在我的 linux 上,我做到了:sudo pip install numexpr --upgrade. -
@Wang 我在
2.6.4。