Pandas替代自定义函数方案:点击流URL多条件匹配与车型名提取
优化点击流数据处理:高效匹配+车型提取方案
我来给你捋一套更高效的实现思路,顺便搞定车型名提取的需求~ 核心是用Pandas的向量化操作替代逐行循环的自定义函数,这在数据量大的时候效率提升特别明显。
第一步:高效实现关键词匹配(替代自定义函数)
咱们先明确逻辑:先过滤出Domains == "BMW"的行,再用三个配置字典分别匹配URL生成结果列。直接用Pandas的str.contains()做向量化匹配,比循环快N倍。
代码示例
import pandas as pd # 假设你的三个配置字典结构如下(按需调整) dict_config = {"config_group1": ["config_val1", "config_val2"], "config_group2": ["config_val3"]} dict_dealer = {"dealer_group1": ["Dealer", "dealer-page"], "dealer_group2": ["dealer-locator"]} dict_brand_keywords = {"brand_group1": ["bmw-official", "bmw-brand"]} # 先筛选BMW的行(后续操作只针对这部分,减少计算量) bmw_subset = df[df["Domains"] == "BMW"].copy() # 把字典里的所有关键词合并成正则匹配串(用|分隔,匹配任意一个关键词) def get_keyword_regex(keyword_dict): return '|'.join([kw for group_vals in keyword_dict.values() for kw in group_vals]) # 生成Is Dealer列 dealer_regex = get_keyword_regex(dict_dealer) bmw_subset["Is Dealer"] = bmw_subset["URL"].str.contains(dealer_regex, case=False, na=False) # 生成另外两个结果列 config_regex = get_keyword_regex(dict_config) bmw_subset["Config Match"] = bmw_subset["URL"].str.contains(config_regex, case=False, na=False) brand_regex = get_keyword_regex(dict_brand_keywords) bmw_subset["Brand Match"] = bmw_subset["URL"].str.contains(brand_regex, case=False, na=False)
为什么这更高效?
- Pandas的字符串方法是向量化实现的,底层用C写的,比Python逐行循环快几个数量级,数据量越大差距越明显。
- 把字典里的所有关键词合并成一个正则串,一次匹配完成,避免重复遍历URL。
第二步:从URL提取车型名
BMW的URL通常会包含车型标识(比如X5、3系、iX这类),咱们用正则匹配来提取最靠谱。先整理常见车型的正则模式,再用str.extract()提取。
代码示例
# 定义BMW常见车型的正则模式(可以根据你的URL实际格式扩展) bmw_model_pattern = r'(3系|5系|7系|X1|X3|X5|X7|i3|iX|i4|M3|M5|Z4)' # 提取车型名到Model Name列 bmw_subset["Model Name"] = bmw_subset["URL"].str.extract(bmw_model_pattern, expand=False) # 如果URL里车型是带前缀的(比如"bmw-x5"、"BMW_3系"),调整正则: # bmw_model_pattern = r'(?:bmw[-_]?)?(3系|5系|X5|iX)' # 这样能匹配到分组里的车型名,忽略前缀 # bmw_subset["Model Name"] = bmw_subset["URL"].str.lower().str.extract(bmw_model_pattern, expand=False)[1]
小技巧
- 用
str.lower()统一转成小写再匹配,避免大小写不统一的问题。 - 如果车型名有变体(比如"X5"和"x5"、"X 5"),可以在正则里加匹配规则:
r'X\s?5'就能匹配"X5"和"X 5"。
第三步:合并回原数据集(可选)
如果需要把结果同步回原DataFrame(而不是只保留BMW的行),可以这样做:
# 先给原DataFrame初始化列的默认值 df["Is Dealer"] = False df["Config Match"] = False df["Brand Match"] = False df["Model Name"] = pd.NA # 把BMW子集的结果赋值回原数据 df.loc[df["Domains"] == "BMW", ["Is Dealer", "Config Match", "Brand Match", "Model Name"]] = bmw_subset[["Is Dealer", "Config Match", "Brand Match", "Model Name"]].values
额外优化建议
- 预编译正则:如果需要多次匹配同一个正则,提前编译能提升效率:
import re compiled_dealer_re = re.compile(dealer_regex, re.IGNORECASE) bmw_subset["Is Dealer"] = bmw_subset["URL"].apply(lambda x: bool(compiled_dealer_re.search(x))) - 批量生成列:如果字典多,写个循环批量处理,避免重复代码:
column_mapping = { "Is Dealer": dict_dealer, "Config Match": dict_config, "Brand Match": dict_brand_keywords } for col_name, keyword_dict in column_mapping.items(): regex = get_keyword_regex(keyword_dict) bmw_subset[col_name] = bmw_subset["URL"].str.contains(regex, case=False, na=False) - 处理缺失值:
str.contains()里加na=False,确保缺失的URL不会返回NaN,而是False,避免后续报错。
内容的提问来源于stack exchange,提问作者s_khan92
相关产品推荐
相关产品推荐

