numpy.trunc 是一个基于abs值的floor函数:
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.])
Run Code Online (Sandbox Code Playgroud)
ceil输出是这样的:
np.ceil(a)
Out[124]: array([-1., -1., -0., 1., 2., 2., 2.])
Run Code Online (Sandbox Code Playgroud)
但我想要一个输出: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 |
Run Code Online (Sandbox Code Playgroud)
所以最好的是rawzero3,它使用inplace操作来减少内存使用,并使copysign加速.
根据@Divakar更新,需要numexpr> = 2.6.4.之前的任何版本都没有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 |
Run Code Online (Sandbox Code Playgroud)
毫无疑问.numexpr版本将提供与rawzero3相同的最佳速度和相同的内存占用.奇怪的部分是rawzero3的内存占用有点不稳定.从理论上讲,它应该只使用2x数组大小而不是3x.
方法1:使用np.where做之间的选择floor和ceil基于的积极/消极-
np.where(a<0, np.floor(a), np.ceil(a))
Run Code Online (Sandbox Code Playgroud)
样品运行 -
In [61]: a
Out[61]: array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2. ])
In [62]: np.where(a<0, np.floor(a), np.ceil(a))
Out[62]: array([-2., -2., -1., 1., 2., 2., 2.])
Run Code Online (Sandbox Code Playgroud)
方法#2:我们可以@Mitch's post通过使用与零和缩放的比较来扩展所使用的符号技巧以获得sign等效,并且还利用numexpr模块来执行ceilon abs值.现在,我们应该记住,numexpr使用大型数据集可以更好地执行.因此,实施将是 -
import numexpr as ne
ne.evaluate('(2*(a>0)-1)*ceil(abs(a))')
Run Code Online (Sandbox Code Playgroud)
运行时测试
所有方法 -
def rawzero1(a):
return np.sign(a)*np.ceil(np.abs(a))
def rawzero2(a):
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
def numexpr_1(a):
return ne.evaluate('(2*(a>0)-1)*ceil(abs(a))')
Run Code Online (Sandbox Code Playgroud)
计时 -
In [52]: a = np.random.randn(1000000)
In [53]: %timeit rawzero1(a)
...: %timeit rawzero2(a)
...: %timeit rawzero3(a)
...: %timeit rawzero4(a)
...: %timeit numexpr_1(a)
...:
100 loops, best of 3: 11.6 ms per loop
100 loops, best of 3: 13.2 ms per loop
100 loops, best of 3: 4.9 ms per loop
100 loops, best of 3: 6.54 ms per loop
1000 loops, best of 3: 1.65 ms per loop
In [54]: np.allclose(numexpr_1(a), rawzero1(a))
Out[54]: True
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
302 次 |
| 最近记录: |