如何基于Pandas对比两个DataFrame拆分数据库企业名称数据
Fixing Pandas Code to Split Company Names by Highest Priority Suffixes
看起来你遇到的核心问题是没有按优先级匹配后缀,而且之前的循环逻辑混乱,导致拆分结果不符合预期。咱们一步步来修复:
先明确你的核心需求:
- 从
TempCompanyName表读取企业名称(你代码里提到了Original_Input和Cleansed_Input,下面统一用Original_Input,你可以根据实际调整) - 匹配
company_Extension中优先级最高的Name_Extension后缀 - 拆分出
Core_Input(去掉后缀的核心名称)和Type_input(对应企业类型) - 无匹配则两列设为NULL
你的原有代码存在的问题
- 没有对关键词表按
Priority降序排序,导致可能先匹配到低优先级的后缀 - 嵌套循环逻辑混乱,没有在找到第一个(最高优先级)匹配后终止查找
- 使用
iloc[i]直接赋值容易触发SettingWithCopyWarning,且效率低下 - 正则匹配没有限定后缀在名称末尾(企业类型后缀通常在名称最后,比如
SRL、BV) - 字符串替换后没有处理末尾的空格
修复后的完整代码
import pandas as pd import re from sqlalchemy import create_engine # 1. 初始化数据库连接(请替换成你的数据库连接字符串) engine = create_engine("mssql+pyodbc://username:password@server/database?driver=ODBC+Driver+17+for+SQL+Server") # 2. 读取两张表 df_companies = pd.read_sql('SELECT * FROM [dbo].[TempCompanyName]', engine) df_extensions = pd.read_sql('SELECT * FROM [dbo].[company_Extension]', engine) # 3. 对关键词表按Priority降序排序——这是处理优先级的核心! # 优先级高的排前面,这样匹配时会先找到最高优先级的后缀 df_extensions_sorted = df_extensions.sort_values(by='Priority', ascending=False).reset_index(drop=True) # 4. 定义拆分函数:对单个企业名称,匹配最高优先级的后缀 def split_company_name(company_name): if pd.isna(company_name): return (None, None) # 处理空值 # 遍历排序后的后缀,找到第一个匹配的 for _, row in df_extensions_sorted.iterrows(): extension = row['Name_Extension'].strip() comp_type = row['Company_Type'].strip() # 正则匹配:后缀在名称末尾,且前面是空格(避免匹配到名称中间的子串) # 使用re.IGNORECASE忽略大小写,re.escape避免特殊字符破坏正则 pattern = re.compile(rf'\s{re.escape(extension)}\s*$', re.IGNORECASE) match = pattern.search(company_name) if match: # 拆分核心名称:去掉匹配到的后缀部分,再清理多余空格 core_name = pattern.sub('', company_name).strip() return (core_name, comp_type) # 没有匹配到任何后缀,返回NULL(对应Pandas的NaN) return (pd.NA, pd.NA) # 5. 批量应用函数到每一行 df_companies[['Core_Input', 'Type_input']] = df_companies['Original_Input'].apply( lambda x: pd.Series(split_company_name(x)) ) # 6. 将结果写回数据库(替换原表,或者用if_exists='append'追加) df_companies.to_sql('TempCompanyName', con=engine, if_exists='replace', index=False) # 打印结果验证 print(df_companies[['Original_Input', 'Core_Input', 'Type_input']])
关键说明
- 优先级处理:通过
sort_values(by='Priority', ascending=False)把高优先级的后缀放在最前面,遍历的时候第一个匹配到的就是优先级最高的,直接返回结果,不需要继续查找低优先级的。 - 正则匹配优化:
- 使用
re.escape(extension)避免后缀里的特殊字符(比如(、))破坏正则表达式 - 用
\s{extension}\s*$限定后缀在名称末尾,且前面是空格,避免误匹配(比如不会把Gosen里的sen当成某个后缀)
- 使用
- 高效赋值:用
apply+pd.Series批量处理,比iterrows循环更高效,也避免了iloc赋值的警告问题。 - 空值处理:对空的企业名称直接返回
None,无匹配的返回pd.NA,写入数据库时会自动转为NULL。
测试示例
假设你的company_Extension表有如下数据:
| Name_Extension | Company_Type | Priority |
|---|---|---|
| SRL | 有限责任公司 | 3 |
| BV | 私人有限公司 | 2 |
| Corporation | 股份公司 | 1 |
处理Original_Input的LARIDENT SRL时,会优先匹配SRL,得到:
- Core_Input:
LARIDENT - Type_input:
有限责任公司
处理ZIMMER MANUFACTURING BV时,匹配BV,得到:
- Core_Input:
ZIMMER MANUFACTURING - Type_input:
私人有限公司
这样就能完全符合你的预期啦!
内容的提问来源于stack exchange,提问作者user12688781
相关产品推荐
相关产品推荐

