#python #numpy
#питон #тупица
Вопрос:
У меня есть вектор значений vals
, вектор частот одинакового измерения freqs
и набор значений частоты pins
.
Мне нужно найти максимальные значения vals
в пределах соответствующего интервала вокруг каждого штыря (от штыря-1 до штыря 1). Однако интервалы сливаются, если они перекрываются (например, [1,2] и [0,5,1,5] становятся [0,5,2]).
У меня есть код, который (я думаю) работает, но я чувствую, что он совсем не оптимален:
import numpy as np np.random.seed(666) freqs = np.linspace(0, 20, 50) vals = np.random.randint(100, size=(len(freqs), 1)).flatten() print(freqs) print(vals) pins = [2, 6, 10, 11, 15, 15.2] # find one interval for every pin and then sum to find final ones islands = np.zeros((len(freqs), 1)).flatten() for pin in pins: island = np.zeros((len(freqs), 1)).flatten() island[(freqs gt;= pin-1) * (freqs lt;= pin 1)] = 1 islands = island islands = np.array([1 if xgt;0 else 0 for x in islands]) print(islands) maxs = [] k = 0 idxs = [] for i,x in enumerate(islands): if (x gt; 0) and (k == 0): # island begins k = 1 idxs.append(i) elif (x gt; 0) and (k gt; 0): # island continues pass elif (x == 0) and (k gt; 0): # island finishes idxs.append(i) maxs.append(np.max(vals[idxs[0]:idxs[1]])) k = 0 idxs = [] continue print(maxs)
Что дает maxs=[73, 97, 79, 77]
.
Ответ №1:
Вот некоторые оптимизации для вашего кода. Есть много функций numpy, которые облегчают вашу жизнь, познакомьтесь с ними и используйте их ;). Я попытался прокомментировать свой код, чтобы сделать его как можно более понятным, но дайте мне знать, если что-то неясно!
import numpy as np np.random.seed(666) freqs = np.linspace(0, 20, 50) vals = np.random.randint(100, size=(len(freqs), 1)).flatten() print(freqs) print(vals) pins = [2, 6, 10, 11, 15, 15.2] # find one interval for every pin and then sum to find final ones islands = np.zeros_like(freqs) # in stead of: np.zeros((len(freqs), 1)).flatten() for pin in pins: island = np.zeros_like(freqs) # see above comment island[(freqs gt;= pin-1) amp; (freqs lt;= pin 1)] = 1 # "amp;" makes it more readable islands = island # in stead of np.array([1 if xgt;0 else 0 for x in islands]) islands = np.where(islands gt; 0, 1, 0) # read as: where "islands gt; 0" put a '1', else put a '0' # compare each value with the next to get island/sea transistions (islands are 1's seas are 0's) island_edges = islands[:-1] != islands[1:] # split at the edges ( 1 to account for starting at the 1 index with comparisons # islands_and_seas is a list of 'seas' and 'islands' islands_and_seas = np.split(islands, np.where(island_edges)[0] 1) # do the same as above but on the 'vals' array islands_and_seas_vals = np.split(vals, np.where(island_edges)[0] 1) # get the max values for the seas and islands max_vals = np.array([np.max(arr) for arr in islands_and_seas_vals]) # create an array where the islands -gt; True, and seas -gt; False islands_and_seas_bool = [np.all(arr) for arr in islands_and_seas] # select only the max values of islands with maxs = max_vals[islands_and_seas_bool] print(maxs)