Python 寻找「;“最佳”;在数据帧中切片而不循环

Python 寻找「;“最佳”;在数据帧中切片而不循环,python,pandas,dataframe,gpx,strava,Python,Pandas,Dataframe,Gpx,Strava,我正在做一个项目,我导入了一个.gpx文件,并将其转换为一个Pandas数据帧进行进一步分析。此文件包含来自Strava、Endomondo、Runkeeper等训练的位置和时间数据。我已经计算了总距离、时间和速度等统计数据,但我还想找出训练中特定距离的最快或最佳时间。所以对于16公里的训练,我想计算一下我在这16公里内最快的5公里、10公里等等 我写了一些有用的东西,但它涉及到在数据帧上循环。由于在数据帧上循环是我应该避免的事情,我觉得应该有一个更有效的解决方案 数据帧的外观如下所示:

我正在做一个项目,我导入了一个.gpx文件,并将其转换为一个Pandas数据帧进行进一步分析。此文件包含来自Strava、Endomondo、Runkeeper等训练的位置和时间数据。我已经计算了总距离、时间和速度等统计数据,但我还想找出训练中特定距离的最快或最佳时间。所以对于16公里的训练,我想计算一下我在这16公里内最快的5公里、10公里等等

我写了一些有用的东西,但它涉及到在数据帧上循环。由于在数据帧上循环是我应该避免的事情,我觉得应该有一个更有效的解决方案

数据帧的外观如下所示:

    distance_dis_3d time_delta
0   0.000000        0.0
1   0.000000        18.0
2   28.229476       1.0
3   5.452599        3.0
4   3.078864        1.0
...
此代码用于查找最快的5000米:

df_selected['distance_cumsum'] = df_selected['distance_dis_3d'].cumsum()
df_selected['time_cumsum'] = df_selected['time_delta'].cumsum()

df_output = pd.DataFrame(columns=['time', 'distance', 'minutes_per_kilometer'])

for i in range(len(df_selected.index)):

    df_xK = df_selected[(df_selected['distance_cumsum'] - df_selected['distance_cumsum'].iat[i]) >= 5000]
    if(len(df_xK.index) != 0):
        time = df_xK['time_cumsum'].iat[0] - df_selected['time_cumsum'].iat[i]
        distance = df_xK['distance_cumsum'].iat[0] - df_selected['distance_cumsum'].iat[i]
        minutes_per_kilometer = (time/60)/(distance/1000)
        df_output = df_output.append({'time': time, 'distance': distance, 'minutes_per_kilometer': minutes_per_kilometer}, ignore_index=True)

best_5k = df_output.loc[df_output['minutes_per_kilometer'].idxmin()]

print('Time 5K:', floor(best_5k['time'] / 60), 'min', floor(best_5k['time'] % 60), 'sec.')
我知道我应该使用矢量化或.apply(),但我不知道如何在这里做到这一点。因此,非常感谢您的帮助!谢谢


可以在这里下载测试文件:

很抱歉,我没有早点给你这个,但我想这就是你要找的

def rollKilos(kilometers):
    df = pd.DataFrame.from_dict({'KM':(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
    ,'Time':(5.3, 5.25, 5.35, 5.36, 5.42, 5.2, 5.25, 5.5, 5.4, 5.15, 5.25, 5.35, 5.3, 5.2, 5.3, 5.1)})
    df = df.set_index('KM')
    return min(df.rolling(kilometers).mean()['Time'][kilometers:])

df.rolling(5).mean()
Out[23]: 
     Time
KM       
1     NaN
2     NaN
3     NaN
4     NaN
5   5.336
6   5.316
7   5.316
8   5.346
9   5.354
10  5.300
11  5.310
12  5.330
13  5.290
14  5.250
15  5.280
16  5.250

rollKilos(5)
Out[30]: 5.249999999999998

rollKilos(3)
Out[31]: 5.200000000000002

rollKilos(10)
Out[32]: 5.279999999999999

对不起,我没有早点给你这个,但我想这就是你要找的

def rollKilos(kilometers):
    df = pd.DataFrame.from_dict({'KM':(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
    ,'Time':(5.3, 5.25, 5.35, 5.36, 5.42, 5.2, 5.25, 5.5, 5.4, 5.15, 5.25, 5.35, 5.3, 5.2, 5.3, 5.1)})
    df = df.set_index('KM')
    return min(df.rolling(kilometers).mean()['Time'][kilometers:])

df.rolling(5).mean()
Out[23]: 
     Time
KM       
1     NaN
2     NaN
3     NaN
4     NaN
5   5.336
6   5.316
7   5.316
8   5.346
9   5.354
10  5.300
11  5.310
12  5.330
13  5.290
14  5.250
15  5.280
16  5.250

rollKilos(5)
Out[30]: 5.249999999999998

rollKilos(3)
Out[31]: 5.200000000000002

rollKilos(10)
Out[32]: 5.279999999999999

您能否提供一个包含最快5000米的示例数据帧,以便提供一个可能的解决方案。还包括预期输出。你是不是先把数据装箱?4k的规则是什么,它属于5k吗?你是在寻找滚动5k(1-5,2-6,3-7…)还是固定的(1-5,6-10,10-15)?@sammywemmy,我添加了一个链接测试文件。使用与此处描述相同的代码将数据转换为数据帧:@datanoveler,我基本上是试图找到累积距离超过5k且累积时间差最小的数据帧片段。您能否提供包含最快5000米的示例数据帧,以便提供可能的解决方案。还包括预期输出。你是不是先把数据装箱?4k的规则是什么,它属于5k吗?你是在寻找滚动5k(1-5,2-6,3-7…)还是固定的(1-5,6-10,10-15)?@sammywemmy,我添加了一个链接测试文件。使用与此处描述相同的代码将数据转换为数据帧:@datanoveler,我基本上是想找到累积距离超过5k且累积时间差最小的数据帧片段。谢谢您的回答!这真的很接近我想要的,但问题是距离和时间不是均匀分布的。我不知道该选什么数字。滚动(#),因为每行的数字可能不同。根据您的示例数据帧,不幸的是,数据看起来更像这样:
df=pd.dataframe.from_dict({'KM':(1,4,5,6,9,10,11,12,14,15,16),'Time':(5.3,5.25,5.5,5.4,5.15,5.25,5.35,5.3,5.2,5.3,5.1)}
所以从1km到5km是3行,但从11km到15km(相同距离)是4行。@Wouterneuwerth抱歉,我没有意识到数据可能是稀疏的。在这种情况下,我唯一能提出的建议是,以1公里为增量创建数据帧,计算数据集中每条记录的平均时间,然后在没有数据的情况下向前填充这些公里数。实际上,您的数据集是不完整的,永远无法准确计算快速5K。如果第一公里很慢,但下一公里很快,而第三公里很慢,那么快的公里将被掩盖。谢谢@Ethan。我想我会坚持我的代码,并接受它需要一点时间来咀嚼所有的数据。:)谢谢你的回答!这真的很接近我想要的,但问题是距离和时间不是均匀分布的。我不知道该选什么数字。滚动(#),因为每行的数字可能不同。根据您的示例数据帧,不幸的是,数据看起来更像这样:
df=pd.dataframe.from_dict({'KM':(1,4,5,6,9,10,11,12,14,15,16),'Time':(5.3,5.25,5.5,5.4,5.15,5.25,5.35,5.3,5.2,5.3,5.1)}
所以从1km到5km是3行,但从11km到15km(相同距离)是4行。@Wouterneuwerth抱歉,我没有意识到数据可能是稀疏的。在这种情况下,我唯一能提出的建议是,以1公里为增量创建数据帧,计算数据集中每条记录的平均时间,然后在没有数据的情况下向前填充这些公里数。实际上,您的数据集是不完整的,永远无法准确计算快速5K。如果第一公里很慢,但下一公里很快,而第三公里很慢,那么快的公里将被掩盖。谢谢@Ethan。我想我会坚持我的代码,并接受它需要一点时间来咀嚼所有的数据。:)