如何在Python中按均值合并重复列值行并排除指定值?
用Python实现重复名称合并均值(排除特定名称)
嘿,这个需求其实挺常见的,我来给你两种实现思路,一种是用pandas(高效简洁,适合数据量稍大的情况),另一种是纯Python原生代码(不用依赖第三方库,轻量灵活)。
方案一:使用pandas库(推荐)
pandas对这类表格数据的分组聚合操作简直是量身定做的,代码量少还不容易出错:
import pandas as pd # 1. 读取文本文件,假设文件名为data.txt # 用\s+匹配任意数量空格,避免多空格导致读取错误,同时给列命名 df = pd.read_csv('data.txt', sep='\s+', header=None, names=['name', 'col1', 'col2', 'col3']) # 2. 拆分数据:需要合并的非特殊名称、原样保留的特殊名称(name7) non_special = df[df['name'] != 'name7'] special_rows = df[df['name'] == 'name7'] # 3. 对非特殊名称分组计算均值,保留1位小数(和示例结果格式匹配) merged_non_special = non_special.groupby('name').mean().round(1).reset_index() # 4. 合并两部分数据,保持顺序(先合并后的非特殊行,再特殊行) result = pd.concat([merged_non_special, special_rows], ignore_index=True) # 5. 按示例格式输出结果 for _, row in result.iterrows(): # 处理整数均值的显示(比如3.0转为3) col1 = int(row['col1']) if row['col1'].is_integer() else row['col1'] col2 = int(row['col2']) if row['col2'].is_integer() else row['col2'] col3 = int(row['col3']) if row['col3'].is_integer() else row['col3'] print(f"{row['name']} {col1} {col2} {col3}")
代码说明:
sep='\s+':兼容文本中任意数量的空格分隔,避免读取异常groupby('name').mean():按名称分组,自动对数值列计算均值round(1):把均值保留1位小数,和你给出的示例结果格式完全匹配- 整数转换处理:避免把3.0这类整数均值显示成小数,更贴合示例输出
方案二:纯Python原生实现(无第三方库)
如果不想依赖pandas,用原生Python也能轻松搞定,核心是用字典累加数值和计数:
# 存储非name7的累计数据:key是名称,value是[数值1总和, 数值2总和, 数值3总和, 出现次数] name_stats = {} # 存储name7的所有原始行 special_rows = [] # 读取并处理文件 with open('data.txt', 'r') as f: for line in f: line = line.strip() if not line: continue parts = line.split() name = parts[0] nums = list(map(float, parts[1:])) if name == 'name7': special_rows.append(line) continue # 初始化或累加统计数据 if name not in name_stats: name_stats[name] = [0.0, 0.0, 0.0, 0] name_stats[name][0] += nums[0] name_stats[name][1] += nums[1] name_stats[name][2] += nums[2] name_stats[name][3] += 1 # 生成合并后的非name7行 merged_rows = [] for name, stats in name_stats.items(): count = stats[3] avg1 = round(stats[0]/count, 1) avg2 = round(stats[1]/count, 1) avg3 = round(stats[2]/count, 1) # 把整数均值转为整数格式 avg1 = int(avg1) if avg1.is_integer() else avg1 avg2 = int(avg2) if avg2.is_integer() else avg2 avg3 = int(avg3) if avg3.is_integer() else avg3 merged_rows.append(f"{name} {avg1} {avg2} {avg3}") # 合并所有行并输出 final_result = merged_rows + special_rows for row in final_result: print(row)
代码说明:
- 用字典
name_stats手动记录每个非特殊名称的数值总和和出现次数,最后计算均值 - 同样做了整数格式转换,保证输出和示例一致
special_rows直接保存所有name7的原始行,最后和合并行拼接输出
两种方案都能得到你想要的结果,数据量小的话纯Python方案足够灵活;数据量大时,pandas的效率会高出不少。
内容的提问来源于stack exchange,提问作者orbit
相关产品推荐
相关产品推荐

