Нахождение «лучшего» среза в Pandas кадре данных без зацикливания - PullRequest
1 голос
/ 30 января 2020

Я работаю над проектом, в котором я импортирую файл .gpx и преобразую его в Pandas фрейм данных для дальнейшего анализа. Этот файл содержит данные о местонахождении и времени тренировок, например, от Strava, Endomondo, Runkeeper и т. Д. Я уже рассчитал статистику, такую ​​как общее расстояние, время и скорость, но затем я также хочу найти самое быстрое или лучшее время для указанных c расстояний в пределах тренировки. Итак, для 16-километровой тренировки я хочу вычислить мои самые быстрые 5k, 10k и т. Д. В пределах этих 16k.

Я написал кое-что, что работает, но это включает в себя циклы по кадру данных. Так как циклирование над фреймом данных - это то, чего я должен избегать, я чувствую, что должно быть более эффективное решение.

Фрейм данных выглядит примерно так:

    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 (), но я не могу понять, как это сделать здесь. Так что любая помощь очень ценится! Спасибо!

Тестовый файл можно скачать здесь: http://gofile.me/2RsVN/dos1tPTVD

1 Ответ

0 голосов
/ 30 января 2020

Извините, я не получил это раньше, но я думаю, это то, что вы ищете.

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
...