python - 查找满足聚合条件的最小连续 pandas 行集

标签 python pandas performance


我有一个数据框,其中包含我最近运行的数据点(通过 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/

相关文章:

python - 当每列都是数组时如何应用数据框

python - 在 Jupyter 中显示来自 Redis 订阅的流数据帧

performance - 是:last-child selector bad for performance?

performance - Sqlite3插入性能测试

python - 为类中的所有函数捕获 "before/after function call"事件

python - 保护 Django OAuth 工具包 View

python - 当同一列具有不同格式时转换 DataFrame 上的日期格式

python - 您如何在 GitHub 操作中使用 pipenv?

Python - 使用反向计数器附加行号

performance - 操作寄存器的正确方法(PUT32 vs GPIO->ODR)