任务说明:
我们也来做一个城市排行榜,从以上排行榜选取10个城市,通过不同维度的评价标准,
统计出每个维度下城市的排名,然后再根据排名的结果得出不同维度下的分数,最后算出每个城市的总分。
评价数据:
1、选取10个城市
2、查询每个城市的以下8项公开数据(如果2019年的数据查询不到,也可以用2018年的代替)
数据维度
(1)2019年GDP
(2)人口数量
(3)平均房价
(4)平均工资
(5)地铁总里程
(6)高校数量
(7)三甲医院数量
(8)小学生数量
评价维度
1.首先按照原榜单给这10个城市打分,并作为新字段写入字典,排名第一得10分,排名最后得1分,以此类推。
2.计算每个城市工资和房价的比值,精确到两位小数,然后将这个数据添加到城市数据中。
截止目前,连上原来的8条数据,每个城市共有10条数据。
3.将每个城市按照10条数据分别进行排名,除房价外,排名第一得10分,排名最后得1分,
以此类推,房价排名第一得1分,排名最后得10分。然后将每个城市的10项数据的得分相加,
得出城市的总得分,满分一百分。最后打印出每个评价维度下每个城市的得分排名情况以及最终总分排名。
读取Excel
# 整体读取
# 1. 从excel读取数据
# 2. 放到字典中
# 3. 再把字典放到列表中
import xlrd # excel read, xlwt excel wirte
# 以下两行代码操作跟我们常规在电脑打开excel的流程一致
book = xlrd.open_workbook('city_data.xlsx') # 双击打开Excel文件(workbook工作薄)
sheet = book.sheet_by_index(0) # 点击打开需要编辑的sheet(sheet工作表)
# 再往下是操作具体的单元格 cell,也就是具体编辑单元格的数据(增删改 查)
main_data_list = [] # 先建立一个空list,等待放入所有的dict
for row in range(3, sheet.nrows): # 观察表格我们发现我们需要的数据从第4行开始
temp_dict = {} # 准备好每条数据需要使用的dict 以行为单位,一行一个dict
print(sheet.row_values(row)) #一行的数据作为列表返回
# 列表基于下标index 取值与关键字key做映射(mapping)
# 注意这里的Key名 和原始的excel有差异,这里涉及到数据的字段名对齐
# 你总不希望你的字段名字 乱七八糟、标点、全角、半角混合 无可读性
temp_dict['城市'] = sheet.row_values(row)[0]
temp_dict['2019GDP'] = sheet.row_values(row)[1]
temp_dict['2018总人口'] = sheet.row_values(row)[2]
temp_dict['2018平均房价'] = sheet.row_values(row)[3]
temp_dict['2018平均工资'] = sheet.row_values(row)[4]
temp_dict['地铁总里程'] = sheet.row_values(row)[5]
temp_dict['高校数量'] = sheet.row_values(row)[6]
temp_dict['三甲医院数量'] = sheet.row_values(row)[7]
temp_dict['2018年小学生数量'] = sheet.row_values(row)[8]
main_data_list.append(temp_dict)
# print(sheet.row_values(3))
len(main_data_list)
main_data_list
# 按照原来的榜单排名顺序给每个城市打分
# 排名第一得10分,排名最后得1分
# 将得分作为**新数据、字段** 添加进城市字典(作为一个数据考量维度)
for i_list in range(len(main_data_list)):
# 穿透的列表 然后穿透到 字典进行操作 # 注意 这里 列表长度-当前的下标刚好= 得分
main_data_list[i_list]['原榜单得分'] = len(main_data_list)-i_list
# 打印原榜单得分
print('城市原榜单得分(由高到低):')
for j_list in range(len(main_data_list)):
print(main_data_list[j_list]['城市'],main_data_list[j_list]['原榜单得分'])
# print('111')
print('-'*80)# 黄金分割线 甩出一条来
# 计算每个城市的收入房价比,精确到2位小数,然后添加到字典作为 新数据、字段
for i in range(len(main_data_list)):
# 注意直接使用format(3.1415,'.2f')和占位'{:2.f}'.format()的区别
main_data_list[i]['收入房价比'] = format(main_data_list[i]['2018平均工资']/12/main_data_list[i]['2018平均房价'])
# 注意这里的收入房间比 工资/12/房均价
# 注意基础数据的更新
main_data_list
注意! 截止目前 以上的业务逻辑都是在处理基础数据!
因为最原始的数据(Excel读取)不够完整
下面进入真正的比较逻辑处理!
# 按照不同的标准对列表中的字典进行排序,注意房价和其他标准打分规则不一样
# 房价为啥打分规则不一样? 因为 常规排名是越多越好,房价? 大家懂得
# 定义一个从字典中取'k'这个key的值的函数
def get_value(dic,k):
return dic.get(k) # 回顾一下 dict.get(k)和dict[key]取值二者有什么区别?
# 做一个 可高度复用的函数 且函数有较高的宽容度(兼容升降两种规则)
def desc_cities(cities_list,kw = '2019GDP'):
if kw!='2018平均房价': # 判断评选标准是不是房价,因为房价和其他标准得分规则不一样。
#----------------------先排序-------------------{{gdp:1000},{},{}]
# 按照kw对列表中的字典进行排序 可迭代对象 调用函数取key对应的value做比较 注意降序100-0
cities_bykey = sorted(cities_list,key= lambda x:get_value(x,kw),reverse=True)
#---------------------再打分-------------------
# 按照kw的排名顺序给每个城市打分,排名第一得10分,最后得1分
# 以此类推,然后将得分作为新数据添加进城市字典
for i_key in range(len(cities_bykey)): #注意这个用法出现第二次了
cities_bykey[i_key][kw+'得分'] = len(cities_bykey)-i_key
# len = 10 i= 0 10-0=10最高分
# 打印每个城市在key评选中的得分
print(f'城市{kw}得分(由高到低):')
for j_key in range(len(cities_bykey)):
print(cities_bykey[j_key]['城市'],cities_bykey[j_key][kw+'得分'])
print('-'*80)
else: # 如果评分是房价的话
# 按照'2018平均房价'对列表中的字典进行排序
cities_bykey = sorted(cities_list,key = lambda x:get_value(x,kw),reverse = True)
# 按照'2018平均房价'的排名顺序给每个城市打分,排名第一得1分,排名最后得10分
# 以此类推,然后将得分作为新数据添加进城市字典
# 特别注意! cities_list本质还是列表 ,基于字典的一个值 排序,那么返回值还是list
# 特别注意! 如果cities_list本质是字典即最外层就是字典那么返回的是[(),()]
for i_house in range(len(cities_bykey)):
cities_bykey[i_house][kw+'得分'] = i_house + 1 # 注意这个逻辑 0+1 最高的分数最低
# 打印每个城市在“2018平均房价”评选中的得分
print(f'城市{kw}得分(由低到高):')
for j_house in range(len(cities_bykey)):
print(cities_bykey[j_house]['城市'],cities_bykey[j_house][kw+'得分'])
print('-'*80)
return cities_bykey
# ******** 批量调用函数 进行排名+单项得分计算 *********
desc_cities(main_data_list,'2019GDP')
desc_cities(main_data_list,'2018总人口')
desc_cities(main_data_list,'2018平均房价')
desc_cities(main_data_list,'2018平均工资')
desc_cities(main_data_list,'地铁总里程')
desc_cities(main_data_list,'高校数量')
desc_cities(main_data_list,'三甲医院数量')
desc_cities(main_data_list,'2018年小学生数量')
cities_bykey = desc_cities(main_data_list,'收入房价比')
# ******* 总结性数据处理 **** 这个是收尾部分 也是成果部分的输出 ********
# 计算城市总得分,然后将总得分作为新数据添加进城市字典
for i_city in range(len(cities_bykey)):
# 把每个维度的数据得分相加,再追加有一个数据(key value进去)城市总得分
cities_bykey[i_city]['城市总得分'] = cities_bykey[i_city]['原榜单得分']+cities_bykey[i_city]['2019GDP得分']+cities_bykey[i_city]['2018总人口得分']+cities_bykey[i_city]['2018平均房价得分']+cities_bykey[i_city]['2018平均工资得分']+cities_bykey[i_city]['地铁总里程得分']+cities_bykey[i_city]['高校数量得分']+cities_bykey[i_city]['三甲医院数量得分']+cities_bykey[i_city]['2018年小学生数量得分']+cities_bykey[i_city]['收入房价比得分']
# 为了整体输出完整,原排行榜分数我再打印一次
print('城市原榜单得分(由高到低)')
for j_list in range(len(main_data_list)):
print(main_data_list[j_list]['城市'],main_data_list[j_list]['原榜单得分'])
# 按照总得分对列表中的字典进行降序排序
cities_byscore = sorted(cities_bykey,key=lambda x:get_value(x,'城市总得分'),reverse = True)
# #打印每个城市的总得分排名
print(f'城市总得分(由高到低)')
for j_score in range(len(cities_byscore)):
print(cities_byscore[j_score]['城市'],cities_byscore[j_score]['城市总得分'])
# 我们看一下 最终的数据 跟之前的比 增加了多少
main_data_list