Нахождение и ранжирование интервалов данных

1

Каждый раз, когда я езжу на своем велосипеде, собирайте второй по второй информации по ряду показателей. Для простоты сделаем вид, что у меня есть файл csv, который выглядит примерно так:

secs, watts,
1,150
2,151
3,149
4,135
.
.
.
7000,160

Таким образом, каждая секунда моей езды имеет связанную с ней мощность, в ваттах.

Я хочу знать: "Если я разорву свою поездку на N вторых блоков, которые блокируют реализовать в высшей средней мощности?"

Я использую pandas dataframe для управления моими данными, и это код, который я использовал для ответа на мой вопрос:

def bestEffort(ride_data,
             metric='watts',
             interval_length=5,
             sort_descending=True):

seconds_in_ride = len(ride_data[metric])

average_interval_list = [[i+1, 
                          np.average(
                             [ride_data[metric][i+j] 
                               for j in range(interval_length)])
                             ] 
                           for i in range(0, 
                                            seconds_in_ride - 
                                                    interval_length)]

average_interval_list.sort(key=lambda x: x[1], reverse=sort_descending)

return average_interval_list

Кажется просто? Правильно? С учетом индекса вычислите среднее значение последующих интервалов interval_length. Следите за этим в списке формы

[[second 1, avg val of metric over the interval starting that second],
 [second 2, avg val of metric over the interval starting that second],
 [second 3, avg val of metric over the interval starting that second],
 .
 .
 .
 [second 7000-interval_length, avg val of metric over the interval starting that second]]

Затем я сортирую полученный список по средним значениям. Итак, первая запись имеет вид

[second_n, avg val of metric over the interval starting in second n]

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

Проблема в том, что если я устанавливаю "interval_length" на что-либо выше 30, это вычисление длится вечно (читайте: более двух минут на приличной машине). Пожалуйста, помогите мне найти, где мой код попадает в узкое место, похоже, что он должен быть быстрее.

Теги:
pandas
numpy
performance

2 ответа

1

Если вы поместите свои данные в массив numpy, скажем, watts, вы можете вычислить среднюю мощность, используя convolve:

mean_power = np.convolve(watts, np.ones(interval_length)/interval_length, mode='valid')

Как вы можете видеть в ссылке np.convolve, эта функция вычисляет локальное среднее первого аргумента, сглаженное с помощью окна, определяемого вторым аргументом. Здесь мы сглаживаем функцию "верхняя шляпа", т.е. Функция "вкл./Выкл.", Которая является постоянной на интервале длины interval_length и в противном случае равна нулю. Это рудиментарно, но дает первую оценку.

Тогда время ваших самых сильных усилий:

time_strongest_effort = np.argmax(mean_power)
0

Здесь используется решение pure-pandas с использованием DataFrame.rolling. Это немного медленнее, чем метод свертывания numpy by @BenBoulderite, но это удобная идиома:

df.rolling(interval_length).mean().shift(-(interval_length - 1))

Для выравнивания средних значений скользящей средней необходим .shift() чтобы результаты были выровнены по левому краю окна качения, а не по правую сторону по умолчанию (документы в DataFrame.rolling).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню