如何基于字符串包含匹配为Pandas DataFrame的model列填充对应值?
我来帮你搞定这个型号匹配填充的问题!你的需求是根据data的title字符串是否包含models里的型号值,来填充data['model']列,之前的方法要么语法错误,要么因为循环覆盖问题没得到正确结果,下面给你几个可行的解决方案:
方案1:使用apply+自定义函数(直观易调试)
这个方法对data的每一行单独处理,优先匹配更长的型号(避免短型号误匹配长型号的子串,比如Nokia和Nokia 5),找不到匹配就保留placeholder。
import pandas as pd # 初始化你的数据集 models = pd.DataFrame({"manufacturer":['Nokia', 'Samsung', 'Motorola', 'Nokia', 'Alcatel', 'Nokia 5'], "model":['3310', 'S4', 'Moto G', 'N1', 'Pixy', 'Nokia 5']}) data = pd.DataFrame({"title":["Brand New Nokia 3310", "Old Samsung S4", "Cool Motorola Moto G", 'New Alcatel', 'Old Nokia 5'], "manufacturer":['Nokia', "Samsung", "Motorola", 'Alcatel', 'Nokia'], "model":["placeholder", "placeholder", "placeholder", "placeholder", "placeholder"]}) # 关键:先按型号长度降序排序,确保长型号先被匹配 models_sorted = models.sort_values(by='model', key=lambda x: x.str.len(), ascending=False) def match_model(title): for model in models_sorted['model']: if model in title: return model return "placeholder" # 应用函数填充model列 data['model'] = data['title'].apply(match_model) print(data)
运行后你会得到正确的结果:
title manufacturer model 0 Brand New Nokia 3310 Nokia 3310 1 Old Samsung S4 Samsung S4 2 Cool Motorola Moto G Motorola Moto G 3 New Alcatel Alcatel placeholder 4 Old Nokia 5 Nokia Nokia 5
方案2:结合厂商+标题双重匹配(更精准)
如果担心不同厂商的型号重名(比如不同厂商都有叫X1的型号),可以同时用manufacturer过滤候选型号,进一步提高匹配准确性:
def match_model_with_manufacturer(row): # 先筛选当前厂商对应的所有型号 candidate_models = models_sorted[models_sorted['manufacturer'] == row['manufacturer']]['model'] for model in candidate_models: if model in row['title']: return model return "placeholder" data['model'] = data.apply(match_model_with_manufacturer, axis=1)
方案3:批量正则替换(高效处理大数据)
如果你的数据集很大,用apply可能效率偏低,可以用正则批量替换的方式:
# 生成正则匹配规则,用|分隔所有型号(长型号在前) pattern = '|'.join(models_sorted['model']) # 批量替换title中的型号为对应值 data['model'] = data['title'].str.replace(pattern, lambda x: x.group(), regex=True) # 把没有匹配到的(替换后和原title一致的)重置为placeholder data['model'] = data.apply(lambda row: row['model'] if row['model'] != row['title'] else 'placeholder', axis=1)
聊聊你之前的错误
- 列表推导式:你写的
[m for m in mod for t in title if m in]语法不完整,而且嵌套循环会生成大量重复值,没法一对一对应到data的每一行。 str.contains循环:title.str.contains(m)返回的是一个布尔Series,不是单个布尔值,而且每次循环会把整个data['model']设置为当前m,后面的匹配会覆盖前面的结果,自然不符合预期。
内容的提问来源于stack exchange,提问作者m1k1
相关产品推荐
相关产品推荐

