“老奶奶”的python学习笔记(19)

2019-12-13  本文已影响0人  菁_在路上

知识体系

第19关:实操项目excel数据整理


第19关:实操项目excel数据整理.jpeg

知识点

明确项目目标

小区房型和朝向数据统计
痛点:房型朝向不同,面积差异,excel录入麻烦

分析过程,拆解目标

这里的关键点是找到数据中的规律,确定可以复用的模版数据。当我们要在Python读写excel的时候,调用csv模块是个很好的选择,所以这一项目可拆解成3个版本,也可以当成是三大步骤。

版本1.0:输入固定表头,确定模板数据
版本2.0:获取模板数据,复用模板数据
版本3.0:写入csv文件,单元间循环

逐步执行,代码实现

版本1.0

固定表头,使用CSV模块

import csv
with open('assets.csv', 'a', newline='') as csvfile:
writer = csv.writer(csvfile, dialect='excel')
header=['小区名称', '地址', '建筑年份', '楼栋', '单元', '户室', '朝向', '面积']
writer.writerow(header)

而小区名,地址这样的信息,一次性输入即可

title = input('请输入小区名称')
address = input('请输入小区地址:')
year = input('请输入小区建造年份:')
block = input('请输入楼栋号:')

版本2.0

缩小范围,会发现在同一单元下,每一楼的户型和朝向一般是一样的。
也就是只需要知道一个单元下某一楼层的数据(朝向和面积),也就是说我们只要拿到起始楼层的每个户室的数据,该单元的其它楼层都可以复用,区别只是户室号。所以,我们可以确定以此为模版数据。

户室号一般是由楼层+后两位序号(以下我会简称为尾号)组成的,如201,202,203,204;301,302,303,304...尾号是统一的,变的只是前面的楼层数(每层加一),所以户室号拆成两部分处理会方便我们后续的操作。

获取模版数据:每次获取数据前得想好我们要用什么样的形式存储数据。在这个案例里,用字典嵌套列表的形式会更方便,其中字典的键是户室号,面积和朝向组成的列表为字典的值。

第一步:获取单个户室信息:

start_floor = input('请输入起始楼层:')

start_floor_rooms = {}
floor_last_number = []

last_number = input('请输入起始楼层户室的尾号:(如01,02)')
floor_last_number.append(last_number)

room_number = int(start_floor + last_number)
direction = int(input('请输入 %d 的朝向(南北朝向输入1,东西朝向输入2):' % room_number ))
area = int(input('请输入 %d 的面积,单位 ㎡ :' % room_number))

start_floor_rooms[room_number] = [direction,area]

第二步:获取本楼层其他户室信息

在此基础上,我们需要加入循环

在收集起始楼层户室号前:
room_loop=True
while room_loop:

在结束后:
continued= input('是否需要输入下一个尾号?按 n 停止输入,按其他任意键继续:')
if continued == 'n':
room_loop = False
else:
room_loop = True

第三步:将这层的数据迁移到其他楼层里

即只需把户室号的楼层数加一,将每一个楼层的字典统一放在一个存放单元级的字典里unit_rooms

unit_rooms = {}
unit_rooms[int(start_floor)] = start_floor_rooms

floor_rooms = {}
for i in range(len(start_floor_rooms)):
number = '4' + floor_last_number[i]
info = start_floor_rooms[int(start_floor + floor_last_number[i])]
floor_rooms[int(number)] = info
unit_rooms[4] = floor_rooms

第四步:将所有楼层的数据一次性放进字典unit_rooms里
加入循环:for floor in range(start_floor + 1, end_floor + 1):
放在为每个楼层建立字典的floor_rooms={}之前

版本3.0

第一步:

如何一次性取出户室号(301-304,401-404,501-504)和户室号对应的朝向和面积?

一种新方法,可以直接遍历字典里所有的值:
for value in DictName.values():
(# value的名字可以自行另取)
(# DictName是要遍历的字典的名称)
(# .values():是固定的用法)

用法举例:
unit_rooms = {3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]},
4:{401:[1,80],402:[1,80],403:[2,90],404:[2,90]},
5:{501:[1,80],502:[1,80],503:[2,90],504:[2,90]}
}
for sub_dict in unit_rooms.values():
print(sub_dict)

遍历字典里所有的键值对:
for k,v in DictName.items():
(#遍历字典的键值对,k对应键,v对应值)
(#k,v 的名字可以自己取,DictName是字典名)

用法举例:
unit_rooms = {3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]},
4:{401:[1,80],402:[1,80],403:[2,90],404:[2,90]},
5:{501:[1,80],502:[1,80],503:[2,90],504:[2,90]}
}
for sub_dict in unit_rooms.values():
for room,info in sub_dict.items():
if info[0] == 1:(本行开始下面4行可以用下述表述来代替:
dire = ['', '南北', '东西']#建立一个列表,第0个元素为空,第1个元素为'南北',第2个元素为'东西')
info[0] = '南北'
elif info[0] == 2:
info[0] = '东西'
print('户室号:%d 朝向: %d 面积:%d' % (room,info[0],info[1]))

打印出的结果是:
...
户室号:401 朝向: 1 面积:80
户室号:402 朝向: 1 面积:80
...

第二步:整合写入csv:

with open('assets.csv', 'a', newline='')as csvfile:
writer = csv.writer(csvfile, dialect='excel')
for sub_dict in unit_rooms.values():
for room,info in sub_dict.items():
dire = ['', '南北', '东西']
writer.writerow([title,address,year,block,unit,room,dire[info[0]],info[1]])

第三步:增加循环

一栋楼里可能会有多个单元,所以我们要在一开始再加入一层单元间的循环。

在最后增加:
unit_continue = input('是否需要输入下一个单元?按 n 停止单元输入,按其他任意键继续:')
if unit_continue == 'n':
unit_loop = False
else:
unit_loop = True

最后结果代码

import csv
(#调用csv模块)
with open('assets.csv', 'a', newline='') as csvfile:
(#调用open()函数打开csv文件,传入参数:文件名“assets.csv”、追加模式“a”、newline='')
writer = csv.writer(csvfile, dialect='excel')
(# 用csv.writer()函数创建一个writer对象)
header=['小区名称', '地址', '建筑年份', '楼栋', '单元', '户室', '朝向', '面积']
writer.writerow(header)

title=input('请输入小区名称:')
address = input('请输入小区地址:')
year = input('请输入小区建造年份:')
block = input('请输入楼栋号:')

unit_loop = True
while unit_loop:
unit=input('请输入单元号:')
start_floor = input('请输入起始楼层:')
end_floor = input('请输入终止楼层:')

(# 开始输入模板数据)
input('接下来请输入起始层每个房间的门牌号、南北朝向及面积,按任意键继续')

start_floor_rooms = {}
floor_last_number = []
(# 收集起始层的房间信息)

(# 定义循环控制量)
room_loop = True
while room_loop:
    last_number = input('请输入起始楼层户室的尾号:(如01,02)')
    floor_last_number.append(last_number)
    (#将尾号用append()添加列表里,如floor_last_number = ['01','02'])
    room_number = int(start_floor + last_number)
    (#户室号为room_number,由楼层start_floor和尾号last_number组成,如301)

    direction = int(input('请输入 %d 的朝向(南北朝向输入1,东西朝向输入2):' % room_number ))
    area = int(input('请输入 %d 的面积,单位 ㎡ :' % room_number))
    start_floor_rooms[room_number] = [direction,area]
    (# 户室号为键,朝向和面积组成的列表为值,添加到字典里,如start_floor_rooms = {301:[1,70]})

    continued= input('是否需要输入下一个尾号?按 n 停止输入,按其他任意键继续:')
    (#加入打破循环的条件)
    if continued == 'n':
        room_loop = False
    else:
        room_loop = True       

unit_rooms = {}
(#新建一个放单元所有户室数据的字典)
unit_rooms[start_floor] = start_floor_rooms
(#unit_rooms={3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]}})
for floor in range(int(start_floor) + 1, int(end_floor) + 1):
(#遍历除初始楼层外的其他楼层)
    floor_rooms = {}
    (#每个楼层都建立一个字典)
    for i in range(len(start_floor_rooms)):
    (#遍历每层有多少个房间,这里是3,即执行for i in range 3 的循环)
        number = str(floor) + floor_last_number[i]
        info = start_floor_rooms[int(start_floor + floor_last_number[i])]
        (# 依次取出字典start_floor_rooms键对应的值,即面积和朝向组成的列表)
        floor_rooms[int(number)] = info
        (#给字典floor_rooms添加键值对,floor_rooms = {401:[1,80]})
    unit_rooms[floor] = floor_rooms

with open('assets.csv', 'a', newline='')as csvfile:
    writer = csv.writer(csvfile, dialect='excel')
    for sub_dict in unit_rooms.values():
        for room,info in sub_dict.items():
            dire = ['', '南北', '东西']
            writer.writerow([title,address,year,block,unit,room,dire[info[0]],info[1]])   

unit_continue = input('是否需要输入下一个单元?按 n 停止单元输入,按其他任意键继续:')
if unit_continue == 'n':
    unit_loop = False
else:
    unit_loop = True

print('恭喜你,资产录入工作完成!')

上一篇 下一篇

猜你喜欢

热点阅读