Create a def function to filter categories in a dataframe

Question:

I´m trying to apply the following rules (picture attached) into the following dataframe (code attached).

enter image description here

data = pd.DataFrame({'col1': [0, 700, 708, 634, 656, 663, 0, 0, 637, 700, 700, 672, 675, 580, 0, 554, 690, 624, 596, 625, 621, 606, 618, 555, 691, 539, 548, 627, 703, 701, 636, 561, 658, 0, 0, 670, 700, 0, 613, 639, 708, 691, 0, 628,
], 
                     'col2': ['SMALL', 'HIGH', 'SELECT', 'MEDIUM', 'SELECT', 'SELECT', 'SMALL', 'HIGH', 'HIGH', 'HIGH', 'SELECT', 'SELECT', 'HIGH', 'HIGH', 'HIGH', 'MEDIUM', 'SELECT', 'SELECT', 'SELECT', 'MEDIUM', 'HIGH', 'MEDIUM', 'MEDIUM', 'HIGH', 'MEDIUM', 'HIGH', 'MEDIUM', 'HIGH', 'SELECT', 'SELECT', 'HIGH', 'MEDIUM', 'SELECT', 'SMALL', 'SMALL', 'SELECT', 'SELECT', 'MEDIUM', 'MEDIUM', 'HIGH', 'SELECT', 'HIGH', 'HIGH', 'SELECT',

]})

A possible way to insert the rules is creating a new column and charge the condition using np.select statement.

Is it possible to create a def function that don´t be so time-consuming instead of this method?
Every help is welcome.
Thanks

data['object'] = np.select(
    [(data['col2'] == 'SMALL') & (data['col1'] >= 100) & (data['col1'] <= 515),
     (data['col2'] == 'SMALL') & (data['col1'] >= 516) & (data['col1'] <= 533),
     (data['col2'] == 'SMALL') & (data['col1'] >= 534) & (data['col1'] <= 555),
     (data['col2'] == 'SMALL') & (data['col1'] >= 556) & (data['col1'] <= 577),
     (data['col2'] == 'SMALL') & (data['col1'] >= 578) & (data['col1'] <= 582),
     (data['col2'] == 'SMALL') & (data['col1'] >= 583) & (data['col1'] <= 615),
     (data['col2'] == 'SMALL') & (data['col1'] >= 616) & (data['col1'] <= 632),
     (data['col2'] == 'SMALL') & (data['col1'] >= 633) & (data['col1'] <= 649),
     (data['col2'] == 'SMALL') & (data['col1'] >= 650) & (data['col1'] <= 999),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 100) & (data['col1'] <= 525),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 526) & (data['col1'] <= 543),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 544) & (data['col1'] <= 555),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 556) & (data['col1'] <= 565),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 566) & (data['col1'] <= 586),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 587) & (data['col1'] <= 598),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 599) & (data['col1'] <= 608),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 609) & (data['col1'] <= 626),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 627) & (data['col1'] <= 635),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 636) & (data['col1'] <= 653),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 654) & (data['col1'] <= 682),
     (data['col2'] == 'MEDIUM') & (data['col1'] >= 683) & (data['col1'] <= 999),
     (data['col2'] == 'HIGH') & (data['col1'] >= 100) & (data['col1'] <= 544),
     (data['col2'] == 'HIGH') & (data['col1'] >= 545) & (data['col1'] <= 562),
     (data['col2'] == 'HIGH') & (data['col1'] >= 563) & (data['col1'] <= 575),
     (data['col2'] == 'HIGH') & (data['col1'] >= 576) & (data['col1'] <= 584),
     (data['col2'] == 'HIGH') & (data['col1'] >= 585) & (data['col1'] <= 591),
     (data['col2'] == 'HIGH') & (data['col1'] >= 592) & (data['col1'] <= 604),
     (data['col2'] == 'HIGH') & (data['col1'] >= 605) & (data['col1'] <= 620),
     (data['col2'] == 'HIGH') & (data['col1'] >= 621) & (data['col1'] <= 635),
     (data['col2'] == 'HIGH') & (data['col1'] >= 636) & (data['col1'] <= 656),
     (data['col2'] == 'HIGH') & (data['col1'] >= 657) & (data['col1'] <= 670),
     (data['col2'] == 'HIGH') & (data['col1'] >= 671) & (data['col1'] <= 679),
     (data['col2'] == 'HIGH') & (data['col1'] >= 680) & (data['col1'] <= 692),
     (data['col2'] == 'HIGH') & (data['col1'] >= 693) & (data['col1'] <= 999),
     (data['col2'] == 'SELECT') & (data['col1'] >= 100) & (data['col1'] <= 564),
     (data['col2'] == 'SELECT') & (data['col1'] >= 565) & (data['col1'] <= 585),     
     (data['col2'] == 'SELECT') & (data['col1'] >= 586) & (data['col1'] <= 606),
     (data['col2'] == 'SELECT') & (data['col1'] >= 607) & (data['col1'] <= 613),
     (data['col2'] == 'SELECT') & (data['col1'] >= 614) & (data['col1'] <= 636),
     (data['col2'] == 'SELECT') & (data['col1'] >= 637) & (data['col1'] <= 646),    
     (data['col2'] == 'SELECT') & (data['col1'] >= 647) & (data['col1'] <= 663),
     (data['col2'] == 'SELECT') & (data['col1'] >= 664) & (data['col1'] <= 683),
     (data['col2'] == 'SELECT') & (data['col1'] >= 684) & (data['col1'] <= 699),
     (data['col2'] == 'SELECT') & (data['col1'] >= 700) & (data['col1'] <= 999)
    ],
    ['Object 1', 'Object 2', 'Object 3', 'Object 4', 'Object 5', 'Object 6', 'Object 7', 'Object 8', 'Object 9', 
     'Object 1', 'Object 2', 'Object 3', 'Object 4', 'Object 5', 'Object 6', 'Object 7', 'Object 8', 'Object 9', 'Object 10', 'Object 11', 'Object 12',
     'Object 1', 'Object 2', 'Object 3', 'Object 4', 'Object 5', 'Object 6', 'Object 7', 'Object 8', 'Object 9', 'Object 10', 'Object 11', 'Object 12', 'Object 13',
     'Object 1', 'Object 2', 'Object 3', 'Object 4', 'Object 5', 'Object 6', 'Object 7', 'Object 8', 'Object 9', 'Object 10', 
     ]) 
Asked By: dsilva

||

Answers:

Use groupby and cut:

bins = {'SMALL': [100, 515, 533, ... ,999],
        'MEDIUM': [100, 525, 543, ... ,999],
        'HIGH': [100, 544, 562, ... ,999],
        'SELECT': [100, 564, 585, ... ,999]
       }

labels = ['object 1', 'object 2', 'object 3', ..., 'object 13'] 

data['new'] = data.groupby('col2')['col1'].transform(lambda g: pd.cut(g, bins=bins[g.name], labels=labels[:len(bins[g.name])-1]))

NB. You can also use a dictionary to define different conditions for each group (labels = {'SMALL': ['A', 'B'...], 'MEDIUM': ['X', 'Y'...]...}). Then use labels=labels[g.name].

Example dummy output (I didn’t use all bins):

    col1    col2       new
0      0   SMALL       NaN
1    700    HIGH  object 3
2    708  SELECT  object 3
3    634  MEDIUM  object 3
4    656  SELECT  object 3
5    663  SELECT  object 3
6      0   SMALL       NaN
7      0    HIGH       NaN
8    637    HIGH  object 3
...
Answered By: mozway