найдите максимальное значение в островах, определенных другим вектором

#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)