Самый чистый способ для бина с помощью Pandas.cut

Целью этого поста является обсуждение в первую очередь, поэтому были бы оценены даже свободные идеи или нити, которые можно потянуть. Я пытаюсь скопировать некоторые данные для анализа, и мне было интересно, что является самым чистым способом хранения моих данных с помощью Pandas.cut, В некоторых случаях я специально пытаюсь разбить диагностические данные ICD-9 на категории и использую этот список в качестве отправной точки. Из того, что я читаю, общий способ сделать это примерно так:

break_points = [0, 139, 239, ...]
labels = ['infectious and parasitic diseases', 'neoplasms', 'endocrine diseases', ...]
df['diag_codes_binned'] = pd.cut(df['diag_codes'],
                                 bins=break_points,
                                 labels=labels)

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

diagnosis_code_dict = {139: 'infectious and parasitic diseases',
                       239: 'neoplasms',
                       279: 'endocrine diseases',
                       ...}

Но функция pd.cut, кажется, не ладит с моим словарем. Похоже, что есть один способ сделать это, используя фрейм данных в качестве таблицы поиска с минимальными и максимальными значениями, показанными здесь, и это представляется одной из возможностей (пример ниже):

In [187]: lkp
Out[187]:
   Min  Max  Val
0    1   99  AAA
1  100  199  BBB
2  200  299  CCC
3  300  399  DDD

И наконец, у меня есть еще одно соображение по поводу набора данных, с которым я работаю наилучшим образом. Некоторые из диагностических кодов начинаются с V или E, и в настоящее время я планирую предварительно обработать их, чтобы преобразовать их в расширение диапазона и обработать их таким образом. Например, если диапазон возможных не-E/V кодов range(0,1000)тогда я мог бы преобразовать E в range(1000, 2000) и V в range(2000, 3000) так, чтобы я мог поддерживать единую таблицу поиска или словарь для всех кодов, из которых я мог бы вырезать сколько угодно ячеек. Тем не менее, этот метод приводит к некоторой потере способности сразу же понять эти коды, поэтому я буду открыт для предложений, если есть лучший способ справиться с этим.

1 ответ

Решение

Я бы просто написал небольшую вспомогательную функцию. Вот одна идея:

import pandas as pd

def bin_helper(code_dict):
    break_points = [0] + sorted(code_dict) #0 added for lower bound on binning
    labels = [code_dict[value] for value in sorted(code_dict)]
    return break_points, labels

# Setting up some minimal reproducible code...
data = {'diag_codes': range(1, 300),
        'diag_codes_binned': ''}
df = pd.DataFrame.from_dict(data)
diag_code_dict = {139: 'infectious and parasitic diseases',
                  239: 'neoplasms',
                  279: 'endocrine diseases'}

# Run the function and drop it into pandas.cut
bins, labels = bin_helper(diag_code_dict)
df['diag_codes_binned'] = pd.cut(df['diag_codes'],
                                 bins=bins,
                                 labels=labels)

Я согласен с тем, что словари (помимо того, что сами по себе являются невероятно быстрой, универсальной структурой данных!) - это очень хороший способ предоставить некоторый контекст в вашем коде о том, что данные должны означать. Я часто использую небольшую функцию "черного ящика" для выполнения реальной работы, если мне нужен словарь, чтобы служить частью моей документации.

Другие вопросы по тегам