Следующий код суммирует числовые данные с использованием двух разных подходов.
Первый подход использует Dataframe (). Description () и пропускает некоторые дополнительные процентили.
* Второй подход отдельно вычисляет итоговую статистику (среднее, стандартное, N), суммирует ее, вычисляет те же квантили, затем добавляет два и сортирует по индексу, так что результат по существу такой же, как и в первомподход.
Существуют некоторые незначительные различия в именах, которые мы можем устранить после слов, и поскольку суммарные данные невелики, это очень быстро.
Оказывается, что использование функции описания было примерно в 8 раз медленнеепример.
Я ищу причины и, возможно, предложения по любым другим подходам, которые могут ускорить это еще больше (фильтры, группы, значения), все они передаются из пользовательского интерфейса в службу торнадо, поэтому скорость важна, поскольку пользователь ожидает результатов, и данные могут быть даже больше, чем в этом примере.
import pandas as pd
import numpy as np
from datetime import datetime
def make_data (n):
ts = datetime.now().timestamp() + abs(np.random.normal(60, 30, n)).cumsum()
df = pd.DataFrame({
'c1': np.random.choice(list('ABCDEFGH'), n),
'c2': np.random.choice(list('ABCDEFGH'), n),
'c3': np.random.choice(list('ABCDEFGH'), n),
't1': np.random.randint(1, 20, n),
't2': pd.to_datetime(ts, unit='s'),
'x1': np.random.randn(n),
'x2': np.random.randn(n),
'x3': np.random.randn(n)
})
return df
def summarize_numeric_1 (df, mask, groups, values, quantiles):
dfg = df[mask].groupby(groups)[values]
return dfg.describe(percentiles = quantiles).stack()
def summarize_numeric_2 (df, filt, groups, values, quantiles):
dfg = df[mask].groupby(groups)[values]
dfg_stats = dfg.agg([np.mean, np.std, len]).stack()
dfg_quantiles = dfg.quantile(all_quantiles)
return dfg_stats.append(dfg_quantiles).sort_index()
%time df = make_data(1000000)
groups = ['c1', 'c2', 't1']
mask = df['c3'].eq('H') & df['c1'].eq('A')
values = ['x1', 'x3']
base_quantiles = [0, .5, 1]
extd_quantiles = [0.25, 0.75, 0.9]
all_quantiles = base_quantiles + extd_quantiles
%timeit summarize_numeric_1(df, mask, groups, values, extd_quantiles)
%timeit summarize_numeric_2(df, mask, groups, values, all_quantiles)
Время на моем ПК для этого:
Использование описания: 873 мс ±8,9 мс на цикл (среднее ± стандартное отклонение из 7 циклов, по 1 циклу каждый)
Использование двухэтапного метода: 105 мс ± 490 мкс на цикл (среднее ± стандартное отклонение из 7 циклов, 10 цикловкаждый)
Все входы приветствуются!