Вычисление среднего для среднего темпа бега (с использованием двух разных pandas dfs) - PullRequest
0 голосов
/ 07 мая 2020

У меня есть два образца данных кадров, и я хотел бы вычислить среднее значение каждого темпа бега (столбцы Avg. Pace). Они представлены так: 5:57, 6:07, et c. Я преобразовал их из объекта, который мне показался обременительным:

previous_week = previous_week.astype({"Distance":'float64', "Runs":'int64', 'Avg. Pace':"datetime64", 'Elev. Gain':'int64'}) 
previous_week['Avg. Pace'] = previous_week['Avg. Pace'].apply(lambda y: str(y))
previous_week['Avg. Pace'] = previous_week['Avg. Pace'].apply(lambda y: datetime.strptime(y, "%Y-%m-%d %H:%M:%S").strftime("%H:%M'"))

current_week = current_week.astype({"Distance":'float64', "Runs":'int64', "Avg. Pace":'datetime64', 'Elev. Gain':'int64'})
current_week['Avg. Pace'] = current_week['Avg. Pace'].apply(lambda y: str(y))
current_week['Avg. Pace'] = current_week['Avg. Pace'].apply(lambda y: datetime.strptime(y, "%Y-%m-%d %H:%M:%S").strftime("%H:%M'"))

Они дают мне желаемый формат (например, 5:57), но все же не позволяют мне вычислить среднее значение. из двух столбцов Avg. Pace при тестировании на данных current_week:

current_week['Avg. Pace'] = current_week['Avg. Pace'].apply(lambda y: pd.to_datetime(y))
df_mean = current_week['Avg. Pace'] - current_week['Avg. Pace'].min().mean() + current_week['Avg. Pace'].min()

я получаю AttributeError: 'str' object has no attribute 'mean' или AttributeError: 'Timestamp' object has no attribute 'mean'. Я бы очень хотел перестать конвертировать туда-сюда - это утомительно. Как получить средний темп бега каждого Athlete в каждом кадре данных?

Примеры данных:

current_week = {'Athlete': {0: 'John M.', 1: 'Tyler L.', 2: 'Matt J.', 3: 'Ben S.', 4: 'Tom C.', 5: 'Tucker C.', 6: 'Jordi P.', 7: 'Robert P.'}, 'Distance': {0: 21.4, 1: 19.4, 2: 16.1, 3: 10.8, 4: 8.3, 5: 6.4, 6: 5.9, 7: 4.8}, 'Runs': {0: 2, 1: 2, 2: 2, 3: 1, 4: 2, 5: 1, 6: 1, 7: 1}, 'Avg. Pace': {0: "06:19'", 1: "05:24'", 2: "04:55'", 3: "05:18'", 4: "07:19'", 5: "05:01'", 6: "05:16'", 7: "05:00'"}, 'Elev. Gain': {0: 524, 1: 45, 2: 4, 3: 81, 4: 67, 5: 67, 6: 34, 7: 53}}

previous_week = {'Athlete': {0: 'John M.', 1: 'Tyler L.', 2: 'Andrew L.', 3: 'Matt J.', 4: 'Ben S.', 5: 'Tom B.', 6: 'Robert P.', 7: 'Tucker C.', 8: 'William M.', 9: 'Tom C.', 10: 'Jordi P.', 11: 'Nick M.'}, 'Distance': {0: 70.3, 1: 43.7, 2: 42.3, 3: 32.2, 4: 31.6, 5: 22.6, 6: 22.0, 7: 18.9, 8: 15.4, 9: 14.9, 10: 13.5, 11: 1.9}, 'Runs': {0: 5, 1: 3, 2: 3, 3: 3, 4: 3, 5: 2, 6: 3, 7: 3, 8: 2, 9: 3, 10: 3, 11: 1}, 'Avg. Pace': {0: "05:57'", 1: "05:31'", 2: "05:47'", 3: "05:07'", 4: "05:43'", 5: "05:12'", 6: "04:52'", 7: "05:00'", 8: "04:48'", 9: "07:43'", 10: "09:48'", 11: "05:04'"}, 'Elev. Gain': {0: 1298, 1: 211, 2: 199, 3: 31, 4: 255, 5: 118, 6: 214, 7: 151, 8: 89, 9: 96, 10: 101, 11: 12}}

1 Ответ

1 голос
/ 07 мая 2020

Я предполагаю, что средний темп никогда не превышает 00:59:59. Если это не так, дайте мне знать.

df = pd.DataFrame(current_week)
# strip that extra ' at the end of the string
df['Avg. Pace'] = df['Avg. Pace'].str.strip("'")
# to_tmedelta to average pace column but add '00:' to get %H%M%S format
df['Avg. Pace'] = pd.to_timedelta('00:'+df['Avg. Pace'])
# get the mean
df['Avg. Pace'].mean()

# Timedelta('0 days 00:05:34')

Или, если вас не волнует преобразование времени в столбце в timedelta, просто используйте numpy.mean непосредственно в списке, созданном из функция map

df = pd.DataFrame(current_week)
# strip that extra ' at the end of the string
df['Avg. Pace'] = df['Avg. Pace'].str.strip("'")
# convert to %H:%M:%S
np.mean(list(map(pd.to_timedelta, '00:'+df['Avg. Pace'])))

# Timedelta('0 days 00:05:34')

Если вы хотите сгруппировать по спортсмену на обе недели, мы concat наши рамки и используем groupby:

df = pd.DataFrame(current_week)
df1 = pd.DataFrame(previous_week)

big_df = pd.concat([df,df1])
big_df['Avg. Pace'] = pd.to_timedelta('00:'+big_df['Avg. Pace'])
# dictionary comprehension for each group
d = {a:d.mean() for a,d in big_df.groupby('Athlete')['Avg. Pace']}

{'Andrew L.': Timedelta('0 days 00:05:47'),
 'Ben S.': Timedelta('0 days 00:05:30.500000'),
 'John M.': Timedelta('0 days 00:06:08'),
 'Jordi P.': Timedelta('0 days 00:07:32'),
 'Matt J.': Timedelta('0 days 00:05:01'),
 'Nick M.': Timedelta('0 days 00:05:04'),
 'Robert P.': Timedelta('0 days 00:04:56'),
 'Tom B.': Timedelta('0 days 00:05:12'),
 'Tom C.': Timedelta('0 days 00:07:31'),
 'Tucker C.': Timedelta('0 days 00:05:00.500000'),
 'Tyler L.': Timedelta('0 days 00:05:27.500000'),
 'William M.': Timedelta('0 days 00:04:48')}

Если вы хотите увидеть среднее значение для Джона М. вы бы просто сделали d['John M.']

Или, если вы предпочитаете создать фрейм вместо словаря

l = [[a, d.mean()] for a,d in big_df.groupby('Athlete')['Avg. Pace']]
mean_df = pd.DataFrame(l, columns=['Athlete', 'Average Pace'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...