У меня есть список бегунов в pandas кадре данных, в котором в столбце «маршрут» сохраняется расстояние бегуна и отслеживаемое отклонение от фактического маршрута. У меня огромный список бегунов ~ 50000, здесь в этом примере я установил n_runners=10000
. Я добавил функцию generate_example_track_data
, которая генерирует пример тестовых данных, которые используются для данных. Каждая запись строки состоит из отслеживаемых данных бегунов в виде списка кортежей (дистанция, отклонение от фактической точки маршрута). Обратите внимание, я не могу изменить этот формат данных, и список отслеживаемых данных также может быть пустым. Мне нужно рассчитать среднее абсолютное отклонение для маршрута каждого бегуна.
Следующий код, который я использую для вычисления этого:
from random import random
n_runners = 10000
def generate_example_track_data(n_samples):
return [(distance, random()*[-1,1][randrange(2)]) for distance in range(n_samples)]
def calculate_runners_dev(values):
if values:
# convert the list [(1, 0.1), (4, 0.005), ..., (32, 0.23)] to an numpy array
arr = np.array([*values])
if arr.shape[0] > 1:
ar = np.sum(np.abs(arr[:, 1]), axis=0) # absolute value of all values and sum them all up
range = np.ptp(arr[:, 0], axis=0)
norm_error = ar / range
return norm_error
else:
return arr[0, 1] # only one entry in the list
else:
return np.nan # empty list
tracked_data = [generate_example_track_data(100) for _ in range(n_runners-1)]
tracked_data.append([])
df = pd.DataFrame({'route': tracked_data})
И сам расчет запускается по:
df['deviation'] = df['route'].apply(calculate_runners_dev)
A %timeit 758 ms ± 28.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
, показал, что расчет довольно медленный.
Мне нужна ваша помощь в том, как оптимизировать функцию calculate_runners_dev
, чтобы уменьшить время ее выполнения. Я только что прочитал о топи c векторизационных функций для повышения скорости. Например, я не уверен, как избежать проверки if-else, содержит ли список данные или нет, и состоит ли он только из одного элемента.