Я столкнулся со следующей проблемой: мне нужно переписать код Matlab в Pandas.
Проблема в следующем: у меня есть данные о разнице в высоте.На основе скользящего окна я определил скользящее среднее и стандартное отклонение высоты.Когда данные по разнице высоты строки больше, чем скользящее среднее + 2 * стандартное значение, это будет считаться «пиком» (который мне нужно определить).Причина в том, что пик может идентифицировать точку крепления, которая не указана в наборе данных.Пока все хорошо.
Теперь самое сложное, что я не могу решить: рядом может быть несколько пиков.Когда пик находится в пределах 10 индексов (1 индекс / строка = 0,25 метра, следовательно, когда пик находится в пределах 2,5 метра) от другого пика, то пики должны быть «объединены»: требуется только пик с самой большой разницей по высоте.сохраняется.Если пик не окружен другим пиком в пределах 10 индексов, то именно это значение сохраняется как самая высокая точка монтажа.
Другое решение может состоять в том, чтобы присвоить этот самый большой разность высот и индекс окружающим пикам.
Я пытался что-то с idxmax () скользящего окна, который не работал.Затем я попробовал следующее, но все еще не могу понять.
Сначала я попытался преобразовать индекс в столбец.Затем я отфильтровал фрейм данных, где heightdiff_peak == True. Затем я рассчитал разницу со следующим индексом.И попытался получить максимальное значение для строк, где текущая строка, где разница меньше 10. Однако это не дает правильного решения.
Кадр данных выглядит следующим образом:
df:
Location abs_diff_height heightdiff_peak index difference_next_index
277 9.00 4.000000 True 277 1.0
278 9.25 5.000000 True 278 74.0
352 27.75 6.900000 True 352 39.0
391 37.50 6.000000 True 391 169.0
560 79.75 6.000000 True 560 1.0
561 80.00 5.900000 True 561 1.0
562 80.25 5.900000 True 562 1.0
563 80.50 8.900000 True 563 1.0
564 80.75 9.900000 True 564 1.0
565 81.00 10.900000 True 565 1.0
566 81.25 13.900000 True 566 1.0
Я попробовал следующий код, но он не работает.
def get_max_value(df):
return df.assign(
max_diff_height = lambda df: np.where(df['difference_next_index']<10,
df['abs_diff_height'].rolling(2).max().shift(1),
df['abs_diff_height'])
)
Я также попробовал что-то вроде:
df[['highest_peak']].rolling(20, center=True).apply(lambda s: s.idxmax(), raw=False)
Однако это приводит только к NaN.
Код Matlab:
%% Snap multiple detections in a row to the highest point of that peak.
% Initialise variables based on first detection value
x=2;
Remember=PeakIndexT(1);
PeakIndex=PeakIndexT(1);
PeakValue=Dataset(PeakIndexT(1));
while x<=length(PeakIndexT)
if PeakIndexT(x)-Remember>10 % If there is more then 10 points (2.5 meters) difference between this and previous detection identify this one as a new one
PeakIndex=[PeakIndex,PeakIndexT(x)];
PeakValue=[PeakValue,Dataset(PeakIndexT(x))];
else % Else merge the detections and use the highest absolute value as the detection peak
if PeakValue(end)<Dataset(PeakIndexT(x))
PeakValue(end)=Dataset(PeakIndexT(x));
PeakIndex(end)=PeakIndexT(x);
end
end
Remember=PeakIndexT(x); % Store previous value for reference in loop
x=x+1;
end
Ожидаемый результат - max_value и индекс.
df:
Location abs_diff_height heightdiff_peak index difference_next_index max_value index_max_value
277 9.00 4.000000 True 277 1.0 5.0 278
278 9.25 5.000000 True 278 74.0 5.0 278
352 27.75 6.900000 True 352 39.0 6.9 352
391 37.50 6.000000 True 391 169.0 6.0 591
560 79.75 6.000000 True 560 1.0 13.9 566
561 80.00 5.900000 True 561 1.0 13.9 566
562 80.25 5.900000 True 562 1.0 13.9 566
563 80.50 8.900000 True 563 1.0 13.9 566
564 80.75 9.900000 True 564 1.0 13.9 566
565 81.00 10.900000 True 565 1.0 13.9 566
566 81.25 13.900000 True 566 1.0 13.9 566