Категоризация данных с сохранением всех значений - PullRequest
0 голосов
/ 07 декабря 2018

У меня большой набор данных, обычно формы > (700000, 5), для которого я хочу выполнить многопараметрическую регрессию.Все переменные зависят друг от друга.Итак, чтобы начать с многопараметрической регрессии, мне нужно разделить данные на подгруппы дискретных интервалов, на которых я могу выполнить однопараметрическую регрессию, чтобы получить первое «чувство» зависимостей.

В настоящее времяЯ использую pd.cut и df.groupby методы pandas, которые до сих пор работают довольно хорошо, если я хочу вычислить среднее значение, сумму или что-либо из классифицированных данных.Мой текущий код показан здесь:

# create sample dataframe
df = pd.DataFrame({'temp_a': np.random.rand(50) * 50 + 20,
                   'temp_b': np.random.rand(50) * 30 + 40,
                   'power_deg': np.random.rand(50),
                   'eta': 1 - np.random.rand(50) / 5},
                  index=pd.date_range(start='20181201', freq='T', periods=50))
# groupby by categorical data:
df_grpd = df.groupby(
    [pd.cut(df.temp_a, np.arange(0, 100, 5)),  # categorical for temp_a
     pd.cut(df.temp_b, np.arange(0, 100, 5)),   # categorical for temp_b
     pd.cut(df.power_deg, np.arange(0, 1, 1 / 20))  # categorical for power_deg
    ]).mean()  # groupby method. THIS is what I do NOT want!
# drop nan
df_grpd = df_grpd[~df_grpd.isna().any(axis=1)]

Это приводит к данным с MultiIndex вроде:

                                  temp_a    ...          eta
temp_a   temp_b   power_deg                 ...             
...
(35, 40] (40, 45] (0.0, 0.05]  35.086985    ...     0.956543
         (45, 50] (0.5, 0.55]  35.204899    ...     0.866111
                  (0.85, 0.9]  37.018165    ...     0.841505
         (50, 55] (0.9, 0.95]  36.087333    ...     0.978163
(40, 45] (45, 50] (0.15, 0.2]  44.235000    ...     0.906970
...

Теперь у меня есть среднее значение значенийкаждая группа , но я хочу сохранить данные каждой группы .Поэтому вместо использования .mean() для groupby я хочу вернуть все значения групп.
Поскольку для этого требуется (по крайней мере, я так полагаю) новый уровень в MultiIndex для данных, я попытался добавить еще один уровень к by=[...] в групповом режиме, но я не смог заставить его работать каким-либо полезным (и презентабельным) способом.Как я хочу, чтобы данные выглядели так:

                                            temp_a       ...          eta
temp_a   temp_b   power_deg    some_int_idx              ...             
...
(35, 40] (40, 45] (0.0, 0.05]  1            37.122355    ...     0.851477
                               2            33.455505    ...     0.980045
         (45, 50] (0.5, 0.55]  1            35.204899    ...     0.866111
                  (0.85, 0.9]  1            37.018165    ...     0.841505
                               2            39.998021    ...     0.800158
         (50, 55] (0.9, 0.95]  1            36.087333    ...     0.978163
(40, 45] (45, 50] (0.15, 0.2]  1            44.235000    ...     0.906970
...

Сводка

Я хочу, чтобы данные групп были перечислены целочисленным индексом some_int_idx.Если в группе более одного пункта данных (поскольку мои фактические данные содержат много точек данных, в «основных» группах будет несколько тысяч точек данных), some_int_idx должно нумеровать эти точки.Если в группе есть только один (или ни один) пункт данных, some_int_idx должно быть 1.Вместо целочисленного индекса можно также использовать временной индекс.

Как я могу это сделать?Заранее спасибо!

1 Ответ

0 голосов
/ 10 декабря 2018

Новый и намного лучший ответ, предоставленный jorisvandenbossche (спасибо!) При подаче отчета об ошибке: я могу просто установить индекс с необходимыми интервалами.Я думаю, иногда просто думать, что прямой и простой способ работает лучше всего ...

df_grpd = df.set_index([pd.cut(df.temp_a, np.arange(0, 100, 5)),  # categorical for temp_a
     pd.cut(df.temp_b, np.arange(0, 100, 5)),   # categorical for temp_b
     pd.cut(df.power_deg, np.arange(0, 1, 1 / 20))  # categorical for power_deg
    ]).sort_index(axis=0)

Старое решение:

(Хорошо, после многих тестов я нашел ответ. Элементы группвы получаете доступ к groupby методом nth() объекта * 1008. * Таким образом, вы можете получить доступ ко всем элементам группы и получить их как полный фрейм данных с помощью:

# groupby by categorical data, WITHOUT MEAN (or any other grouping method):
df_grpd = df.groupby(
    [pd.cut(df.temp_a, np.arange(0, 100, 5)),  # categorical for temp_a
     pd.cut(df.temp_b, np.arange(0, 100, 5)),   # categorical for temp_b
     pd.cut(df.power_deg, np.arange(0, 1, 1 / 20))  # categorical for power_deg
    ])  # groupby method. Do NOT use this!

df_grpd_full = df_grpd.nth([range(df.shape[0])])

ПоследнийСтрока, конечно, также может быть переписана с помощью:

n_grps = 0
while not df_grpd.nth(n_grps).empty:
    n_grps += 1

df_grpd_full = df_grpd.nth([range(n_grps)])

)

Возможная ошибка?

Но странно, начиная со второй группы (df_grpd.nth(1)), метод группировкикажется, прослушивается.Только первый параметр groupby, в этом случае temp_a, кажется, будет в порядке.Другие параметры, по-видимому, находятся вне интервала группировки.Я отправлю сообщение об ошибке на github и выложу ссылку. сообщение об ошибке

...