当得到Counter()函数得到的排序结果后,如何得到有序的键呢?你在这里可以得到答案!
下面以深度学习图像分类问题引入Counter()函数,假设现在有一个文件,记录了最后迭代的五次、在测试集上预测错误的图片的信息,现在要统计每一张预测错误的图片在这五次迭代中总共预测错误的次数、以及预测成错误的类别对应的次数。例如:在五次迭代中,rgb-028-057.JPG这张图片五次都被预测错了,其中预测成第55类为4次,预测为33类为1次,要求预测错误的图片按照预测失败的次数从高到低的顺序排序。则格式如下:rgb-028-057.JPG,5,{‘55’: 4, ‘33’: 1}
原始文件如下:
下面分步解决此问题
1、提取文件中所有图片id
f=open('C:\\Users\\Hou bin\\Desktop\\error_bird216_50_5.txt','r',encoding = 'utf-8')
ls=[]
for i in f.readlines():
i=i.strip().split()
i=i[0].split(":")[-1]
ls.append(i)
print("去重之前,共有{:}张图片".format(len(ls)))
f.close()
2、去重、并求每张图片预测错误的次数、并以此为标准把分类错误的图片从高到低排序
问题:在利用Counter()函数求出每张图片被预测错误的次数后,虽然进行了排序,但是后续还要统计所有预测成错误的类别的次数,并要求按照预测错误的次数从高到低排序,赋值给变量C后,发现这是一个<class ‘collections.Counter’>类型,本想转化成字典的键值对类型,却失去了原来有序的状态…
利用list()方法取<class ‘collections.Counter’>类型中的键!也失去了原先键的有序状态,无奈,只好自己寻找方法…
**解决:**1、利用list()方法,把C中的键的无序状态保存到一个列表中
2、遍历该列表,利用C的索引方法,把键和键的值加到一个小列表中、小列表再嵌套到大列表中,便于后续排序
3、利用sort方法对嵌套列表进行排序,用到了匿名函数lambda
4、就可以得到有序的列表
from collections import Counter
import collections
C=Counter(ls)
l=list(C)
LS=[]
for i in range(len(l)):
t=[]
t.append(l[i])
key=l[i]
t.append(C[key])
LS.append(t)
#print(LS)
LS.sort(key=lambda x:x[-1],reverse=True)
for i in range(len(LS)):
print(LS[i])
print(len(LS))
结果如下(l列表是有序的):
3、求预测成错误的类别的次数
基本思想就是按照第二步得到的键的有序状态(这就是为什么我想方设法的要求出键的有序状态),逐行遍历原文件中的每一行,若发现该键在此行中,说名该键对应的图片被预测错误了一次,先提取预测成的错误的类别、作为键,然后对该键的值进行加一操作,可用字典的.get()方法完成。具体见代码吧,还涉及到字典的嵌套,就是把图片的id作为最外层的键!
import re
f=open('C:\\Users\\Hou bin\\Desktop\\error_bird216_50_5.txt',"r", encoding = 'utf-8' )
f2=open('C:\\Users\\Hou bin\\Desktop\\error_bird216_50_5_SORT.txt','w', encoding = 'utf-8' )
Dict_={}
for j in range(len(LS)):
dict_={}
f.seek(0)
for i in f.readlines():
if LS[j][0] in i:
key= re.findall(r"\d+",i[-4:-1])[0]
dict_[key]=dict_.get( key ,0)+1
Dict_[LS[j][0]]=dict_
print("{:},{},{:}".format(LS[j][0],LS[j][1],dict_),flush=True,file=f2)
f2.close()
最后的结果如下:
有需要练手的童鞋可以把源文件拿走!反正这几行代码对Python语法要求蛮高的!
复制这段内容后打开百度网盘App,操作更方便哦。 链接:https://pan.baidu.com/s/1Nldj4nK8bcPkojbTa1eO2w 提取码:5521