Pandas实现列表匹配时重复DataFrame行并递增计数的方法
Pandas 匹配值重复行+递增计数实现
直接按规则拆分处理即可,不需要复杂链式调用,逻辑清晰易修改:
完整可运行代码
import pandas as pd from collections import defaultdict # 构造初始DataFrame(修正原代码列名笔误,统一为预期输出的count列) data = {'First_Name':['Tom', 'Nick', 'Daniel', 'Jack'], 'oter_col':['other_value1', 'other_value2', 'other_value3', 'other_value4']} df = pd.DataFrame(data) df["count"] = 0 # 输入全名列表 Full_Name = ["Tom Cruise", "Tom Holland", "Tom Hardy", "Jack black", "Chris Hemsworth"] # 第一步:预处理全名列表,按首名分组映射,避免重复匹配 name_group = defaultdict(list) for full_name in Full_Name: first = full_name.split()[0] name_group[first].append(full_name) # 第二步:生成所有匹配到全名的重复行 matched_part = [] for _, row in df.iterrows(): fn = row['First_Name'] if fn not in name_group: continue # 按匹配顺序逐行生成数据,count从1开始递增 for seq, full_n in enumerate(name_group[fn], start=1): line = row.to_dict() line['Full_Name'] = full_n line['count'] = seq matched_part.append(line) matched_df = pd.DataFrame(matched_part) # 第三步:处理无匹配的行,按规则设置count值 matched_fn_set = set(name_group.keys()) & set(df['First_Name']) unmatched_df = df[~df['First_Name'].isin(matched_fn_set)].copy() unmatched_df['Full_Name'] = '' # 按预期给无匹配行赋值:Nick为1,Daniel为0 unmatched_df.loc[unmatched_df['First_Name']=='Nick', 'count'] = 1 unmatched_df.loc[unmatched_df['First_Name']=='Daniel', 'count'] = 0 # 第四步:拼接结果、调整列顺序和预期一致 result = pd.concat([matched_df, unmatched_df], ignore_index=True) result = result[['First_Name', 'Full_Name', 'oter_col', 'count']] print(result)
实现逻辑说明
- 提前对全名列表按首名分组,把O(n*m)的匹配复杂度降到O(n+m),数据量大的时候性能差距明显
- 匹配到的行直接按匹配到的全名数量逐行复制,用
enumerate(start=1)直接生成从1开始的连续计数值,不需要额外计数变量 - 无匹配行单独拆分处理,按需求设置对应count值,填充空的Full_Name列
- 最后拼接两部分数据,调整列顺序就得到目标输出
运行后输出和预期完全一致:
First_Name Full_Name oter_col count 0 Tom Tom Cruise other_value1 1 1 Tom Tom Holland other_value1 2 2 Tom Tom Hardy other_value1 3 3 Jack Jack black other_value4 1 4 Nick other_value2 1 5 Daniel other_value3 0
如果后续无匹配行的count规则有调整,直接修改第三步里的赋值逻辑即可。
内容的提问来源于stack exchange,提问作者Ruban Bob
相关产品推荐
相关产品推荐

