查找和排列数据的间隔

时间:2018-06-15 01:40:24

标签: python performance pandas numpy

每次骑自行车时,都会按照许多指标的第二个数据进行收集。为简单起见,我们假设我有一个类似于:

的csv文件
secs, watts,
1,150
2,151
3,149
4,135
.
.
.
7000,160

因此,我乘坐的每一秒都有一个相关的功率值,单位为瓦特。

我想知道"如果我把我的骑行分成N个第二个区块,哪个区块能够以最高的平均功率实现?"

我使用pandas数据框来管理我的数据,这是我用来回答我的问题的代码:

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]

告诉我,我在给定间隔长度上的最大努力始于我锻炼中的second_n。

问题是,如果我设置" interval_length"对于高于30的任何东西,这个计算需要永远(读取:在一台体面的机器上超过两分钟)。请帮助我找到我的代码遇到瓶颈的地方,这似乎应该更快。

2 个答案:

答案 0 :(得分:1)

如果您将数据放在一个numpy数组中,比如watts,您可以使用convolve计算平均功率:

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

正如您在the reference of np.convolve中看到的,此函数计算第一个参数的局部均值,并使用第二个参数定义的窗口进行平滑处理。在这里,我们顺利地采用了#34; top-hat"功能 - 即。 "开/关"函数在长度interval_length的区间内是常数,否则为零。这是初步的,但给出了初步估计。

然后你最努力的时间是:

time_strongest_effort = np.argmax(mean_power)

答案 1 :(得分:0)

这是使用DataFrame.rolling的纯熊猫解决方案。它比@BenBoulderite的numpy卷积方法略慢,但是方便的习惯用语:

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

需要.shift()来对齐滚动平均值,以便结果与滚动窗口的边缘对齐,而不是默认的右边缘({{3 }})。