我有以下 df 和函数(见下文)
。我可能把这个复杂化了。我们将不胜感激一双全新的眼睛。
df:
Site Name Plan Unique ID Atlas Placement ID
Affectv we11080301 11087207850894
Mashable we14880202 11087208009031
Alphr uk10790301 11087208005229
Alphr uk19350201 11087208005228
目标是:
先通过
df['Plan Unique ID']
迭代,搜索特定值(we_match
或uk_match
),如果有匹配检查字符串值是否大于该组中的特定值(
we12720203
或uk11350200
)如果该值大于将
<we 或 uk 值
添加到新列df['Consolidated ID']
。如果值较低或没有匹配项,则使用
搜索new_id_search
df['Atlas Placement ID']
如果有匹配项,则将其添加到
df['Consolidated ID']
如果不是,返回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