I've got an array of (random) floating point numbers. I want to round each value up to a limit of an arbitrary grid. See the following example:
import numpy as np
np.random.seed(1)
# Setup
sample = np.random.normal(loc=20, scale=6, size=10)
intervals = [-np.inf, 10, 12, 15, 18, 21, 25, 30, np.inf]
# Round each interval up
for i in range(len(intervals) - 1):
sample[np.logical_and(sample > intervals[i], sample <= intervals[i+1])] = intervals[i+1]
This results in:
[ 30. 18. 18. 15. 30. 10. inf 18. 25. 21.]
How can I avoid the for
loop? I'm sure there's some way using NumPy's array magic that I don't see right now.
If intervals
is sorted, you can use np.searchsorted
:
np.array(intervals)[np.searchsorted(intervals, sample)]
# array([ 30., 18., 18., 15., 30., 10., inf, 18., 25., 21.])
searchsorted
returns the index of the interval where the element belongs to:
np.searchsorted(intervals, sample)
# array([7, 4, 4, 3, 7, 1, 8, 4, 6, 5])
The default side='left'
returns the smallest index of such interval and the result falls into the left open, right close scenario.
You can use Pandas cut()
:
import pandas as pd
pd.cut(sample, intervals, labels=intervals[1:]).tolist()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With