代码之家  ›  专栏  ›  技术社区  ›  canconfirm24

使用字典和模式匹配填充列值

  •  0
  • canconfirm24  · 技术社区  · 2 年前

    我正在对信用卡交易进行分类。现在,我正在使用一个与np.select()组合的字典,如下所示:

        def cat_mapper(frame, targ_col, cat_col):
        
            category_retailers = {'Online Shopping':['amazon','amzn mktp', 'target.com'],
                                  'Wholesale Stores': ['costco', 'target'],
                                 }
            cond = [frame[targ_col].str.contains('|'.join(category_retailers['Online Shopping']),regex=True,case=False),
                    frame[targ_col].str.contains('|'.join(category_retailers['Wholesale Stores']),regex=True,case=False),
                   ]
    
            choice = ['Online Shopping',
                      'Wholesale Stores'
                     ]
           
            default_cond = frame[cat_col]
    
            frame[cat_col] = np.select(cond, choice, default_cond)
            return frame
    

    其中frame参数是数据帧,targ_col参数是具有事务描述或名称的Description列,cat_col参数是将包含事务类别的category列。

    基本前提是检查事务描述列中字典值的部分匹配,如果描述中存在部分匹配,则将相应的字典键分配给类别列。

    上面的块的功能没有问题,但有一些冗余。必须定义字典值,然后将字典值与np.select的相应条件和选项相匹配。

    有没有一种方法可以将事务描述与字典中的值列表进行模式匹配,并将字典键分配给类别列,而不使用np.select作为中介?

    我想我可以使用嵌套循环,但即使这样也显得很冗长。有没有更雄辩的方法来实现同样的结果。

    示例数据帧:

    data_dict = {'Description': ['amazon 345689','amzn mktp online 7765','amazon 4444','costco location','Wholefoods'],
               'Category':['NaN','NaN','NaN','NaN','Groceries']
              }
    df = pd.DataFrame(data=data_dict)
    

    样本输出:

    data_dict = {'Description': ['amazon 345689','amzn mkpt online 7765','amazon 4444','costco location','Wholefoods'],
               'Category':['Online Shopping','Online Shopping','Online Shopping','Online Shopping','Groceries']
              }
    df = pd.DataFrame(data=data_dict)
    

    上面的示例输出应该可以使用下面的代码块和我当前的np.select()框架进行复制。

    import pandas as pd
    import numpy as np
    
    
    def cat_mapper(frame, targ_col, cat_col):
    
        category_retailers = {'Online Shopping':['amazon','amzn mktp', 'target.com'],
                                'Wholesale Stores': ['costco', 'target'],
                                }
        cond = [frame[targ_col].str.contains('|'.join(category_retailers['Online Shopping']),regex=True,case=False),
                frame[targ_col].str.contains('|'.join(category_retailers['Wholesale Stores']),regex=True,case=False),
                ]
    
        choice = ['Online Shopping',
                    'Wholesale Stores',
                    ]
    
        default_cond = frame[cat_col]
    
        frame[cat_col] = np.select(cond, choice, default_cond)
        return frame
    
    data_dict ={'Description': ['amazon 345689','amzn mktp online 7765','amazon 4444','costco location','Wholefoods'],
               'Category':['NaN','NaN','NaN','NaN','Groceries']
              }
    
    
    df = pd.DataFrame(data=data_dict)
    
    cat_mapper(df,'Description','Category')
    

    提前感谢,如果您需要我提供任何其他详细信息,请告诉我

    1 回复  |  直到 2 年前
        1
  •  1
  •   mozway    2 年前

    您可以通过使用列表理解来计算条件并利用字典键/值来重构代码:

    def cat_mapper(frame, targ_col, cat_col):
        category_retailers = {'Online Shopping':['amazon','amzn mktp', 'target.com'],
                              'Wholesale Stores': ['costco', 'target'],
                             }
        cond = [frame[targ_col].str.contains('|'.join(val),regex=True,case=False)
                for val in category_retailers.values()]
    
        frame[cat_col] = np.select(cond, list(category_retailers), frame[cat_col])
        return frame
    
    cat_mapper(df, 'Description', 'Category')
    

    输出

                 Description          Category
    0          amazon 345689   Online Shopping
    1  amzn mkpt online 7765               NaN  # not matching because of typo
    2            amazon 4444   Online Shopping
    3        costco location  Wholesale Stores
    4             Wholefoods         Groceries
    

    使用的输入:

    data_dict = {'Description': ['amazon 345689','amzn mkpt online 7765','amazon 4444','costco location','Wholefoods'],
                 'Category':['Nan','Nan','Nan','Nan','Groceries']
              }
    df = pd.DataFrame(data=data_dict).replace('Nan', float('nan'))