Группировка панд с максимальной оптимизацией скользящего среднего - PullRequest
0 голосов
/ 14 мая 2018

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

Код сначала устанавливает определенные интервалы для группировки данных, и для каждой группировки требуется скользящая средняя. Как только он получит все эти средние значения, он сохранит максимум для этого интервала в новом кадре данных и перейдет к следующему интервалу. Это делается для всех тренировок в наборе данных ('best_interval_df'), а также для последней тренировки в наборе данных ('latest_df'), поэтому самые последние тренировки можно сравнить с рекордным максимумом.

Есть ли другой способ, которым я мог бы приблизиться к этому, который бы ускорил время обработки?

Пример данных можно найти здесь: https://www.dropbox.com/s/so4fo99q8ttkh24/samples.csv?dl=0

# 1 second intervals from 0-60 seconds
interval_lengths = [i for i in range(1, 61)]
# 15 second intervals from 1:15 - 5:00 mins
interval_lengths += [i for i in range(75, 301, 15)]
# 30 second intervals for 5:00 - 10:00
interval_lengths += [i for i in range(330, 601, 30)]
# 1 minute intervals for everything after 10 mins
interval_lengths += [i for i in range(660, df_samples['seconds_since_pedaling_start'].apply(
    lambda x: int(math.ceil(x / 10.0)) * 10).max() + 1, 60)]

intervals = df_samples.sort_index(ascending=True)
intervals['power'] = intervals['power'].interpolate()  # Used to fill in missing gaps in data
latest_df = intervals[intervals['workoutId'] == intervals.loc[intervals.index.max]['workoutId']]
latest_df_length = latest_df['seconds_since_pedaling_start'].max()

best_interval_df = pd.DataFrame()
latest_interval_df = pd.DataFrame()
for i in interval_lengths:
    # Get interals for all time
    temp_df = intervals
    temp_df['best_power'] = intervals.groupby(['workoutId'])['power'].rolling(int(i),
                                                                              min_periods=i - 1).mean().reset_index(
        0,
        drop=True)
    temp_df['interval'] = i
    best_interval_df = best_interval_df.append(temp_df.loc[temp_df['best_power'].idxmax()])

    # Don't insert intervals for periods longer than the latest workout
    if i <= latest_df_length:
        latest_temp_df = latest_df
        latest_temp_df['best_power'] = latest_df.groupby(['workoutId'])['power'].rolling(int(i),
                                                                                         min_periods=i - 1).mean().reset_index(
            0, drop=True)
        latest_temp_df['interval'] = i
        latest_interval_df = latest_interval_df.append(latest_temp_df.loc[latest_temp_df['best_power'].idxmax()])

best_interval_df['datetime'] = best_interval_df.index
best_interval_df = best_interval_df.set_index('interval')
latest_interval_df['datetime'] = latest_interval_df.index
latest_interval_df = latest_interval_df.set_index('interval')

Теперь также попытались сгенерировать список данных, а затем объединить, в отличие от добавления к df в цикле ... Все еще очень медленно:

# 1 second intervals from 0-60 seconds
interval_lengths = [i for i in range(1, 61)]
# 15 second intervals from 1:15 - 5:00 mins
interval_lengths += [i for i in range(75, 301, 15)]
# 30 second intervals for 5:00 - 10:00
interval_lengths += [i for i in range(330, 601, 30)]
# 1 minute intervals for everything after 10 mins
interval_lengths += [i for i in range(660, df_samples['seconds_since_pedaling_start'].apply(
    lambda x: int(math.ceil(x / 10.0)) * 10).max() + 1, 60)]

intervals = df_samples.sort_index(ascending=True)
intervals['power'] = intervals['power'].interpolate()  # Used to fill in missing gaps in data
latest_df = intervals[intervals['workoutId'] == intervals.loc[intervals.index.max]['workoutId']]
latest_df_length = latest_df['seconds_since_pedaling_start'].max()

best_interval_df_list = []
latest_interval_df_list = []
for i in interval_lengths:
    # Get interals for all time
    temp_df = intervals
    temp_df['best_power'] = intervals.groupby(['workoutId'])['power'].rolling(int(i),
                                                                              min_periods=i - 1).mean().reset_index(
        0,
        drop=True)
    temp_df['interval'] = i
    # Append list with best power record for given interval
    best_interval_df_list.append(temp_df.loc[temp_df['best_power'].idxmax()])

    # Don't insert intervals for periods longer than the latest workout
    if i <= latest_df_length:
        latest_temp_df = latest_df
        latest_temp_df['best_power'] = latest_df.groupby(['workoutId'])['power'].rolling(int(i),
                                                                                         min_periods=i - 1).mean().reset_index(
            0, drop=True)
        latest_temp_df['interval'] = i
        # Append list with best power record for given interval
        latest_interval_df_list.append(latest_temp_df.loc[latest_temp_df['best_power'].idxmax()])

# Merge lists of series into df
latest_interval_df = pd.DataFrame(latest_interval_df_list)
best_interval_df = pd.DataFrame(best_interval_df_list)

best_interval_df['datetime'] = best_interval_df.index
best_interval_df = best_interval_df.set_index('interval')
latest_interval_df['datetime'] = latest_interval_df.index
latest_interval_df = latest_interval_df.set_index('interval')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...