【问题标题】:Create column based on multiple column conditions from another dataframe根据来自另一个数据框的多个列条件创建列
【发布时间】:2019-03-19 04:50:20
【问题描述】:

假设我有两个数据框 - 条件和数据。

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”:

(class= 4 AND 160

(class= 4 AND 160

(class= 5 AND 160

(class= 5 AND 160

任何不符合任何条件的行都将被分配到组“其他”。因此,最终的数据框将如下所示:

+-------+---------+-----------+-------+
| 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     |
+-------+---------+-----------+-------+

【问题讨论】:

    标签: python pandas numpy pandas-groupby multiple-conditions


    【解决方案1】:

    您可以迭代 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 的结果与您想要的输出不同,因为有多个条件满足数据。

    【讨论】:

      猜你喜欢
      • 2020-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 2020-04-04
      • 2017-01-17
      • 2021-03-22
      • 1970-01-01
      相关资源
      最近更新 更多