numpy.trunc
is a floor function based on abs value:
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.])
The ceil output is this:
np.ceil(a)
Out[124]: array([-1., -1., -0., 1., 2., 2., 2.])
But I want an output: array([-2., -2., -1., 1., 2., 2., 2.]) What is the numpy function for this?
edit: Unfortunately there is no build-in round away from zero function. Based on @Mitch and @Divakar answers I did some test and try to optimize the speed and memory usage.
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 |
so the best is rawzero3, which use inplace operations to reduce memory usage and copysign to speed up.
update according to @Divakar which requires numexpr >=2.6.4. Any version before that does not have 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 |
There is no surprise at all. numexpr version will give the best speed and same memory footprint as rawzero3. The weird part is rawzero3's memory footprint is kind of unstable. Theoretically it should only use 2x array size instead of 3x.