Создать столбец на основе нескольких условий столбца из другого кадра данных

1

Предположим, у меня есть два кадра данных - условия и данные.

import pandas as pd

conditions = pd.DataFrame({'class': [1,2,3,4,4,5,5,4,4,5,5,5],
                           'primary_lower': [0,0,0,160,160,160,160,160,160,160,160,800],
                           'primary_upper':[9999,9999,9999,480,480,480,480,480,480,480,480,4000],
                           'secondary_lower':[0,0,0,3500,6100,3500,6100,0,4800,0,4800,10],
                           'secondary_upper':[9999,9999,9999,4700,9999,4700,9999,4699,6000,4699,6000,3000],
                           'group':['A','A','A','B','B','B','B','C','C','C','C','C']})

data = pd.DataFrame({'class':[1,1,4,4,5,5,2],
                     'primary':[2000,9100,1100,170,300,210,1000],
                     'secondary':[1232,3400,2400,380,3600,4800,8600]})

Я хотел бы создать новый столбец (группу) в таблице "данных", который присваивает группу каждой строке, учитывая условия, указанные в таблице "условия".

Таблица условий структурирована так, что строки внутри каждой группы объединяются с помощью "OR", а столбцы объединяются "AND". Например, для назначения группы "B":

(класс = 4 И 160 <= первичный <= 480 И 3500 <= вторичный <= 4700)

ИЛИ ЖЕ

(класс = 4 И 160 <= первичный <= 480 И 6100 <= вторичный <= 9999)

ИЛИ ЖЕ

(класс = 5 И 160 <= первичный <= 480 И 3500 <= вторичный <= 4700)

ИЛИ ЖЕ

(класс = 5 И 160 <= первичный <= 480 И 6100 <= вторичный <= 9999)

Любые строки, которые не соответствуют ни одному из условий, получат назначенную группу "Другое". Итак, окончательный файл данных будет выглядеть следующим образом:

+-------+---------+-----------+-------+
| class | primary | secondary | group |
+-------+---------+-----------+-------+
|     1 |    2000 |      1232 | A     |
|     1 |    9100 |      3400 | A     |
|     4 |    1100 |      2400 | Other |
|     4 |     170 |       380 | C     |
|     5 |     300 |      3600 | B     |
|     5 |     210 |      4800 | C     |
|     2 |    1000 |      8600 | A     |
+-------+---------+-----------+-------+
Теги:
pandas
numpy
pandas-groupby
multiple-conditions

1 ответ

1
Лучший ответ

Вы можете GroupBy объект GroupBy и принимать объединение масок в каждой группе:

for key, grp in conditions.groupby('group'):

    cols = ['class', 'primary_lower', 'primary_upper',
            'secondary_lower', 'secondary_upper']

    masks = (data['class'].eq(cls) & \
             data['primary'].between(prim_lower, prim_upper) & \
             data['secondary'].between(sec_lower, sec_upper) \
             for cls, prim_lower, prim_upper, sec_lower, sec_upper in \
             grp[cols].itertuples(index=False))

    data.loc[pd.concat(masks, axis=1).any(1), 'group'] = key

data['group'] = data['group'].fillna('Other')

Результат:

print(data)

   class  primary  secondary  group
0      1     2000       1232      A
1      1     9100       3400      A
2      4     1100       2400  Other
3      4      170        380      C
4      5      300       3600      C
5      5      210       4800      C
6      2     1000       8600      A

Примечание index=4 имеет другой результат для вашего желаемого результата, так как существует множество условий, которые удовлетворяют данным.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню