我有一个数据框,其中包含我最近运行的数据点(通过 Strava API)。数据框有两列:
| time_elapsed | distance_covered |
-----------------------------------
| 1 | 1.1 |
| 2 | 2.3 |
| 3 | 3.2 |
...
| 5876 | 15200.3 |
两列都是累积的。我现在想找到我在锻炼中跑的最快 5 公里,即连续行的子集,使得
行[-1]['distance_covered']-row[0]['distance_covered'] >= 5000
row[-1]['time_elapsed'] - row[0]['time_elapsed']
已最小化
我的以下解决方案有效;然而它相当慢并且感觉不是特别优雅,因为我本质上是多次迭代相同的行。
distance_time = defaultdict(list)
for i in range(df.shape[0]):
working_df = df.iloc[i:].copy()
previous = df.iloc[i]['distance_covered']
working_df['distance_covered'] = working_df['distance_covered'] - previous
ix = np.argmax(working_df['distance_covered'] > 5000)
if ix == 0:
break
else:
distance_time[5000].append(working_df.iloc[ix]['time_elapsed'] - working_df.iloc[0]['time_elapsed'])
fastest_time = np.nanmin(distance_time[5000])
另一种方法是计算间隔时间,然后使用 cumsum,但我仍然需要从每个可能的起始行查看数据帧,所以我认为它不会更快。
有人有更好的想法/更快的方法来实现相同的结果吗?
编辑:df.head(10).to_dict() 的实际示例输出
{'time_elapsed': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9}, 'distance_covered': {0: 1.1, 1: 2.3, 2: 4.4, 3: 7.1, 4: 9.7, 5: 12.3, 6: 15.6, 7: 18.7, 8: 21.7}}
最佳答案
设置
df = pd.DataFrame(
{
'time_elapsed': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9},
'distance_covered': {0: 1.1, 1: 2.3, 2: 4.4, 3: 7.1, 4: 9.7, 5: 12.3, 6: 15.6, 7: 18.7, 8: 21.7}
},
)
解决方案
下面我假设时间以秒为单位,距离以米为单位。问题中没有说明这一点,如果不正确,则需要进行调整。
插入初始点:
df.iloc[-1,:] = [0,0]
将 distance_covered
设置为索引,然后以 0.1m (10cm) 间隔重新索引并插入时间列。当索引是基于时间的时,这类似于“重新采样”
interpolated = (
df
.set_index("distance_covered")
.sort_index()
.reindex(np.arange(0,int(df["distance_covered"].max())+1, 0.1))
.interpolate()
)
`interpolated 是一个具有单列的数据帧。看起来像这样
time_elapsed
distance_covered
0.0 0.000000
0.1 0.090909
0.2 0.181818
0.3 0.272727
0.4 0.363636
... ...
18.5 7.937500
18.6 7.968750
18.7 8.000000
18.8 8.000000
18.9 8.000000
数据仍然是累积的,因此我们取连续值之间的差值,然后进行滚动求和,即 50000 行 = 50000 x 0.1m = 5km
interpolated["time_elapsed"].diff().rolling(50000).sum()
这将为您提供一个系列,按行驶距离索引,值是行驶前 5 公里所用的时间。从那里找到系列(或情节等)中的最大值
关于python - 查找满足聚合条件的最小连续 pandas 行集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74103564/