Как использовать Pandas для вычисления групповой статистики быстрее? - PullRequest
1 голос
/ 08 октября 2019

У меня есть огромный массив данных, в котором хранится информация о встречах пациентов и переменных, связанных с их жизненно важными показателями и лабораторными тестами.

str_df.shape
(278546, 34)
str_df.columns
Index(['hadm_id', 'ce_charttime', 'hr', 'sbp', 'dbp', 'map', 'resp', 'temp',
       'spo2', 'glucose', 'base_excess', 'hco3', 'fio2', 'ph', 'paco2', 'sao2',
       'ast', 'bun', 'alp', 'calcium', 'chloride', 'creatinine',
       'bilirubin_direct', 'bilirubin_total', 'lactic_acid', 'magnesium',
       'potassium', 'troponin', 'hematocrit', 'hemoglobin', 'ptt', 'wbc',
       'fibrinogen', 'platelets'],
      dtype='object')

Я хочу рассчитать статистику изменений для каждой встречи с пациентом (hadm_id) в течение 24 часов. Обратите внимание, что этот набор данных довольно редок в том смысле, что многие переменные в большинстве случаев имеют NaN с.

Я придумал этот код, который был протестирован на очень маленькомподмножество данных и, кажется, работает:

def percentile(n):
  def percentile_(x):
    return x.quantile(n)
  percentile_.__name__ = f'percentile_{n*100:2.0f}'
  return percentile_

def get_stats(df, var_cols, statistics):
  df.set_index('ce_charttime', inplace=True) # change index to charttime to use '24h' on rolling
  stats_dfs = []

  # loop through each var for which change statistics needs to be computed
  for var in var_cols:
    stats_df = df.groupby('hadm_id')[var].rolling('24h').agg(statistics).reset_index(drop=True) # compute stats
    stats_df.columns = [f'{var}_{col}' for col in stats_df.columns] # create var dependent names for stats
    stats_df = pd.concat([df[var].reset_index(drop=True), stats_df], axis=1) # cat the original var value to preserve order 
    stats_dfs.append(stats_df) # add the stats for this parituclar var to the list

  df.reset_index(inplace=True) # remove charttime index
  df.drop(var_cols, inplace=True, axis=1) # drop the original var cols (we've added it in the for loop)
  return pd.concat([df, *stats_dfs], axis=1) # cat the list into a df
statistics = ['min', 'mean', 'median', 'std', 'var', 'kurt', 'skew', percentile(0.25), percentile(0.75), stats.iqr, 'max']
var_cols = str_df.columns[2:]

str_df = get_stats(str_df.copy(), var_cols, statistics)

# reorder columns
move = ['hadm_id', 'ce_charttime']
order = move + (str_df.columns.drop(move).tolist())
str_df = str_df[order]

К сожалению, когда я пытаюсь запустить это для всего набора данных, это занимает слишком много времени и приводит к сбою моего ноутбука Jupyter. Интересно, это из-за петель for, которые я использую. Есть ли более питон / панды способ выполнения этой задачи?

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...