如何用itemgetter()/Counter实现CSV多条件迭代统计?
统计投诉最多产品的及时响应率问题解决
我是Python新手,正在解析一份消费者金融产品及服务投诉的CSV文件,文件共16列,需统计出现次数最多的Product对应的Timely Response(Yes/No字段)的及时响应率。
已通过itemgetter()获取到投诉最多的产品:
for row in reader: id_counts = Counter(map(itemgetter(1), reader)) pprint(id_counts)
返回结果:
Counter({'Credit reporting, credit repair services, or other personal consumer reports': 112, 'Debt collection': 32, 'Mortgage': 12, 'Credit card or prepaid card': 11, 'Checking or savings account': 11, 'Student loan': 5, 'Money transfer, virtual currency, or money service': 4, 'Vehicle loan or lease': 4, 'Payday loan, title loan, or personal loan': 1})
遇到的问题
尝试统计该产品的及时响应情况时,两段代码均出现异常:
- 错误统计所有行的响应结果:
for row in reader: if row[1] == 'Credit reporting, credit repair services, or other personal consumer reports': c = Counter(map(itemgetter(15), reader)) print(c)
返回:
Counter({'Yes': 186, 'No': 4})
- 抛出"不支持的操作数"错误:
for row in reader: if row[1] == 'Credit reporting, credit repair services, or other personal consumer reports': c = Counter(row[15].split()) print(sum(c))
错误原因分析
- 第一段代码:CSV reader是迭代器,在
for row in reader循环中调用map(itemgetter(15), reader)会直接耗尽迭代器,跳过判断逻辑,导致统计了所有行的响应数据。 - 第二段代码:
row[15]本身是单个"Yes"/"No"字符串,split()操作无意义,且每次循环单独创建Counter无法实现累加统计,最终引发错误。
解决方案(基于itemgetter和Counter)
方法一:两次遍历实现(逻辑清晰)
from collections import Counter from operator import itemgetter import csv # 替换为你的CSV文件路径 with open('complaints.csv', 'r', newline='', encoding='utf-8') as f: reader = csv.reader(f) next(reader) # 跳过表头(如果文件有表头的话) # 第一次遍历:统计所有产品的投诉数量 product_counter = Counter(map(itemgetter(1), reader)) # 获取投诉量最高的产品 target_product = product_counter.most_common(1)[0][0] # 重置文件指针,重新读取 f.seek(0) next(reader) # 第二次遍历:收集目标产品的响应数据 target_responses = [] for row in reader: if row[1] == target_product: target_responses.append(row[15]) # 统计响应情况并计算及时响应率 response_counter = Counter(target_responses) total_complaints = sum(response_counter.values()) timely_rate = response_counter.get('Yes', 0) / total_complaints * 100 print(f"目标产品:{target_product}") print(f"响应统计:{response_counter}") print(f"及时响应率:{timely_rate:.2f}%")
方法二:一次遍历完成(效率更高)
from collections import Counter, defaultdict from operator import itemgetter import csv with open('complaints.csv', 'r', newline='', encoding='utf-8') as f: reader = csv.reader(f) next(reader) # 用字典存储每个产品对应的所有响应数据 product_responses = defaultdict(list) for row in reader: product = row[1] response = row[15] product_responses[product].append(response) # 获取投诉量最高的产品 target_product = max(product_responses, key=lambda k: len(product_responses[k])) # 统计响应并计算及时响应率 response_counter = Counter(product_responses[target_product]) total_complaints = len(product_responses[target_product]) timely_rate = response_counter.get('Yes', 0) / total_complaints * 100 print(f"目标产品:{target_product}") print(f"响应统计:{response_counter}") print(f"及时响应率:{timely_rate:.2f}%")
内容的提问来源于stack exchange,提问作者Gosha
相关产品推荐
相关产品推荐

