Skip to main content
 首页 » 编程设计

python之Pandas Dataframe 上的条件正则表达式函数

2024年10月01日12xiaohuochai

我有以下 df 和函数(见下文)。我可能把这个复杂化了。我们将不胜感激一双全新的眼睛。

df:

Site Name   Plan Unique ID  Atlas Placement ID 
Affectv     we11080301      11087207850894 
Mashable    we14880202      11087208009031 
Alphr       uk10790301      11087208005229 
Alphr       uk19350201      11087208005228 

目标是:

  1. 先通过df['Plan Unique ID']迭代,搜索特定值(we_matchuk_match),如果有匹配

  2. 检查字符串值是否大于该组中的特定值(we12720203uk11350200)

  3. 如果该值大于将 we 或 uk 值 添加到新列 df['Consolidated ID']

    <
  4. 如果值较低或没有匹配项,则使用 new_id_search

    搜索 df['Atlas Placement ID']
  5. 如果有匹配项,则将其添加到 df['Consolidated ID']

  6. 如果不是,返回0给df['Consolidated ID]

当前的问题是它返回一个空列。

 def placement_extract(df="mediaplan_df", we_search="we\d{8}", uk_search="uk\d{8}", new_id_search= "(\d{14})"): 
 
        if type(df['Plan Unique ID']) is str: 
            we_match = re.search(we_search, df['Plan Unique ID']) 
            if we_match: 
                if we_match > "we12720203": 
                    return we_match.group(0) 
                else: 
                    uk_match =  re.search(uk_search, df['Plan Unique ID']) 
                    if uk_match: 
                        if uk_match > "uk11350200": 
                            return uk_match.group(0) 
                        else: 
                            match_new =  re.search(new_id_search, df['Atlas Placement ID']) 
                            if match_new: 
                                return match_new.group(0) 
 
                            return 0 
 
 
    mediaplan_df['Consolidated ID'] = mediaplan_df.apply(placement_extract, axis=1) 

编辑:清理公式

我按照以下方式修改了gzl的函数(见下文):首先查看df1中是否有14个数字。如果是这样,请添加。

下一步,理想情况下是从 df2 中获取列 MediaPlanUnique 并将其转换为一系列 filtered_placements:

we11080301   
we12880304   
we14880202   
uk19350201   
uk11560205   
uk11560305   

并查看 filtered_placements 中的任何值是否存在于 df['Plan Unique ID] 中。如果匹配,则将 df['Plan Unique ID] 添加到我们的末尾列 = df[ConsolidatedID]

当前的问题是它的结果全为 0。我认为这是因为比较是按 1 比 1 进行的(new_match 的第一个结果 vs filtered_placements 的第一个结果) 而不是一对多(new_match 的第一个结果 vs filtered_placements 的所有结果)

有什么想法吗?

def placement_extract(df="mediaplan_df", new_id_search="[a-zA-Z]{2}\d{8}", old_id_search= "(\d{14})"): 
 
    if type(df['PlacementID']) is str: 
 
        old_match =  re.search(old_id_search, df['PlacementID']) 
        if old_match: 
            return old_match.group(0) 
 
        else: 
 
            if type(df['Plan Unique ID']) is str: 
                if type(filtered_placements) is str: 
 
 
                    new_match = re.search(new_id_search, df['Plan Unique ID']) 
                    if new_match: 
                        if filtered_placements.str.contains(new_match.group(0)): 
                            return new_match.group(0)           
 
 
        return 0 
 
mediaplan_df['ConsolidatedID'] = mediaplan_df.apply(placement_extract, axis=1) 

请您参考如下方法:

我建议不要使用如此复杂的嵌套 if 语句。正如 Phil 所指出的,每张支票都是互斥的。因此,您可以在同一个缩进的 if 语句中检查“we”和“uk”,然后回退到默认过程。

def placement_extract(df="mediaplan_df", we_search="we\d{8}", uk_search="uk\d{8}", new_id_search= "(\d{14})"): 
 
    if type(df['Plan Unique ID']) is str: 
        we_match = re.search(we_search, df['Plan Unique ID']) 
        if we_match: 
            if we_match.group(0) > "we12720203": 
                return we_match.group(0) 
 
        uk_match =  re.search(uk_search, df['Plan Unique ID']) 
        if uk_match: 
            if uk_match.group(0) > "uk11350200": 
                return uk_match.group(0) 
 
 
        match_new =  re.search(new_id_search, df['Atlas Placement ID']) 
 
        if match_new: 
            return match_new.group(0) 
 
        return 0 

测试:

In [37]: df.apply(placement_extract, axis=1) 
Out[37]: 
0    11087207850894 
1        we14880202 
2    11087208005229 
3        uk19350201 
dtype: object