PySpark匹配企业名称后缀与字典列表值返回对应国家
PySpark企业名称后缀匹配国家实现方案
- 输入字典:
terms_by_country,键为国家名称,值为对应国家通用企业名称后缀(如LLC、s.a.、pty ltd等)列表 - 输入数据集:存储企业信息的PySpark DataFrame,包含
id、org_name(企业全称)两个字段 - 预处理中间表:已转换生成的
keywordsDataFrame,包含country(国家名)、value(对应国家后缀列表)两列 - 需求:检测
org_name字段是否包含字典内的企业后缀,存在匹配项时新增列返回该后缀对应的国家名称 - 现存问题:初始join逻辑错误使用国家名做正则匹配,无法实现字符串类型
org_name列与列表类型value列的匹配判断
复现用基础代码
字典构造代码
terms_by_country = { "United States": ["LLC", "Inc.", "Corp."], "Brazil": ["s.a.", "ltda."], "Australia": ["pty ltd", "ltd"], "Germany": ["gmbh", "ag"] }
keywords生成逻辑
from pyspark.sql import SparkSession spark = SparkSession.builder.appName("org_suffix_match").getOrCreate() keywords = spark.createDataFrame( [(country, suffix_list) for country, suffix_list in terms_by_country.items()], schema=["country", "value"] )
样例企业数据
org_df = spark.createDataFrame([ (1, "Acme Corp."), (2, "Sydney Trading pty ltd"), (3, "Sao Paulo Manufacturing s.a."), (4, "Berlin Tech gmbh"), (5, "Global Independent Shop") ], schema=["id", "org_name"])
原有错误实现代码
from pyspark.sql.functions import expr # 错误逻辑:使用国家名做正则匹配规则,未调用后缀列表字段 wrong_result = org_df.join(keywords, expr("org_name rlike country"), how="left")
正确实现步骤
核心问题点:
keywords表的value列是数组类型,无法直接和字符串类型的org_name做匹配,必须先将数组展开为每个后缀单独一行的格式,再基于后缀做匹配判断。
- 展开后缀数组,统一大小写避免匹配遗漏
用explode函数把每个国家的后缀列表拆成单条的国家-后缀映射记录,同时统一转小写,解决大小写不一致导致的匹配失败问题。 - 基于业务规则做关联匹配
企业后缀通常出现在名称末尾,优先用结尾匹配规则减少误判;如果业务要求只要名称任意位置包含后缀就算匹配,替换成包含判断即可。 - 去重处理
避免一个企业匹配到多个后缀时出现重复id的记录。
完整实现代码:
from pyspark.sql.functions import explode, lower, col # 展开后缀数组 keyword_exploded = keywords.select( "country", explode("value").alias("suffix") ).withColumn("suffix_lower", lower(col("suffix"))) # 关联匹配 match_result = org_df.withColumn("org_name_lower", lower(col("org_name"))) \ .join( keyword_exploded, # 后缀在名称末尾用endswith,任意位置包含替换为contains即可 col("org_name_lower").endswith(col("suffix_lower")), how="left" ) \ .drop("suffix", "suffix_lower", "org_name_lower") \ .dropDuplicates(["id"])
精度优化提示
如果需要避免短后缀误匹配(比如德国后缀"ag"匹配到单词"again"中的字符),可以用正则词边界+结尾锚定规则替换匹配条件,同时转义后缀中的正则特殊字符(比如后缀里的.),示例:
from pyspark.sql.functions import expr, regexp_replace # 替换join中的匹配条件,要求后缀为独立词且出现在名称末尾 match_condition = expr("org_name_lower rlike concat('\\\\b', regexp_replace(suffix_lower, '([.\\\\+*?\\[\\](){}|^$])', '\\\\$1'), '$')")
如果存在一个企业匹配多个国家后缀的场景,可以给后缀加长度权重,优先匹配更长的后缀(比如优先匹配"pty ltd"而非单独的"ltd"),进一步降低误判率。
内容的提问来源于stack exchange,提问作者peer wild
相关产品推荐
相关产品推荐

