使用Pandas的groupby与聚合函数实现多列计算,完成不同邮编区域内企业声誉评分
解决Pandas分组统计好评率及排名的问题
看起来你已经迈出了第一步,但在分组统计好评数和排名上遇到了小麻烦,我来帮你一步步搞定这四个计算列——用Pandas做这个可比Excel高效太多,再也不会崩溃啦!
先明确下核心需求:针对每个邮编区域(或者你之前尝试的邮编+企业组合),计算总记录数、好评数、好评率,最后基于好评率做排名。我会先按单邮编区域演示,再补充邮编+企业组合的情况。
完整实现代码(单邮编区域统计)
我们可以用groupby结合agg一次性完成前三个列的计算,再用rank()轻松搞定排名:
import pandas as pd # 你的原始DataFrame df = pd.DataFrame({ 'zip,company': ["46062|A","11236|B","11236|C","11236|C","11236|C","11236|A","11236|A","11236|A","11236|B","11236|B","11236|A","11236|A","11236|B","11236|A","11236|A","11236|B","11236|A","11236|A"], 'goodbadscore': ["good","bad","bad","good","good","bad","bad","good","good","good","bad","good","good","good","good","bad","bad","good"], 'postlcode' : ["46062","11236","11236","11236","11236","46062","11236","46062","11236","11236","11236","11236","11236","11236","11236","11236","11236","11236"], 'companyname': ["A","B","C","C","C","A","A","A","B","B","A","A","B","A","A","B","A","A"] }) # 1. 按邮编分组,一次性计算总记录数和好评数 result = df.groupby('postlcode').agg( countinzipcode=('postlcode', 'count'), # 统计每组总记录数 countgoodscoreinzip=('goodbadscore', lambda x: (x == 'good').sum()) # 统计每组中"good"的数量 ).reset_index() # 2. 计算好评率(需要保留小数的话可以加.round(2)) result['dividegoodscore%'] = result['countgoodscoreinzip'] / result['countinzipcode'] # 3. 基于好评率排名(降序,好评率越高排名越靠前) # method='min'表示相同好评率的邮编共享同一个最高排名,可按需换成'dense'/'max'等 result['ranking'] = result['dividegoodscore%'].rank(method='min', ascending=False).astype(int) print(result)
关键问题解析
为什么你之前统计好评数得到0?
大概率是分组后的数据结构没处理对,或者判断逻辑有误。用agg里的lambda x: (x == 'good').sum()是直接对每组的goodbadscore列做向量化判断:等于"good"的会变成True(即数值1),求和后就是该组的好评总数,这样就不会出现统计为0的问题啦。
关于排名的实现细节
Pandas的rank()函数非常灵活,这里的参数说明:
ascending=False:因为要让好评率高的排名靠前,所以用降序method='min':如果多个邮编好评率相同,它们会获得相同的最小排名(比如两个邮编好评率都是0.7,都排第1)astype(int):把排名转换成整数,更符合日常习惯
如果你需要其他排名规则,可以调整method参数:
'dense':相同值排名相同,后续排名不跳过(比如两个第1,下一个直接是第2)'max':相同值取最大排名(比如两个第2,下一个是第3)
如果需要统计邮编+企业的组合(对应你之前的groupby(['zip+company']))
只需要把分组列改成['postlcode', 'companyname']即可,代码调整如下:
# 按邮编+企业分组统计 result = df.groupby(['postlcode', 'companyname']).agg( countinzipcode=('postlcode', 'count'), countgoodscoreinzip=('goodbadscore', lambda x: (x == 'good').sum()) ).reset_index() # 好评率和排名计算和之前一致 result['dividegoodscore%'] = result['countgoodscoreinzip'] / result['countinzipcode'] result['ranking'] = result['dividegoodscore%'].rank(method='min', ascending=False).astype(int) print(result)
为什么Pandas比Excel好用?
Pandas基于numpy的向量化运算,处理几十万条数据都不会像Excel那样崩溃,而且代码可以重复运行,后续修改需求只需要调整几行代码,完全不用手动重复操作,效率提升不是一点半点!
内容的提问来源于stack exchange,提问作者Oliver Wu
相关产品推荐
相关产品推荐

