Получить максимальное значение строк в диапазоне индекса - PullRequest
1 голос
/ 05 июля 2019

Я столкнулся со следующей проблемой: мне нужно переписать код 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

1 Ответ

2 голосов
/ 05 июля 2019

IIUC, вам нужно groupby сначала:

s = df.difference_next_index.shift().gt(10)
df['index_max_value'] = (df.abs_diff_height                          
                           .groupby([s,s.cumsum()])
                           .transform('idxmax')
                         )

дает:

277    278.0
278    278.0
352    352.0
391    391.0
560    566.0
561    566.0
562    566.0
563    566.0
564    566.0
565    566.0
566    566.0
Name: abs_diff_height, dtype: float64

и получение значений просто

df['max_value'] = df.loc[df['index_max_value'],'abs_diff_height']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...