The answer is almost never np.vectorize
. You can, and should, do this in a fully vectorized manner. Let's say that for x >= 0
, you want r = floor(x + 0.5)
. If you want negative numbers to round towards zero, the same formula applies for x < 0
. So let's say that you always want to round away from zero. In that case, you are looking for ceil(x - 0.5)
for x < 0
.
To implement that for an entire array without calling np.vectorize
, you can use masking:
def round_half_up(x):
mask = (x >= 0)
out = np.empty_like(x)
out[mask] = np.floor(x[mask] + 0.5)
out[~mask] = np.ceil(x[~mask] - 0.5)
return out
Notice that you don't need to use a mask if you round all in one direction:
def round_up(x):
return np.floor(x + 0.5)
Now if you want to make this really efficient, you can get rid of all the temp arrays. This will use the full power of ufuncs:
def round_half_up(x):
out = x.copy()
mask = (out >= 0)
np.add(out, 0.5, where=mask, out=out)
np.floor(out, where=mask, out=out)
np.invert(mask, out=mask)
np.subtract(out, 0.5, where=mask, out=out)
np.ceil(out, where=mask, out=out)
return out
And:
def round_up(x):
out = x + 0.5
np.floor(out, out=out)
return out
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…