我有一个数据结构,我们称之为库存,在CSV中,类似于:
ResID,Building,Floor,Room,Resource
1.1.1.1,Central Park,Ground,Admin Office,Router
1.1.2.1,Central Park,Ground,Machine Closet,Router
1.3.1.1,Central Park,Mezzanine,Dungeon,Whip
2.1.3.1,Chicago,Roof,Pidgeon Nest,Weathervane
1.13.4.1,Central Park,Secret/Hidden Floor,c:\room,Site-to-site VPN for 1.1.1.1
1.2.1.1,Central Park,Balcony,Restroom,TP 我试图让它以排序后的CSV格式输出,并以以下格式的文本文件格式输出:
1 Central Park
1.1 Ground
1.1.1 Admin Office
1.1.1.1 Router
1.1.2 Machine Closet
1.1.2.1 Router
1.2 Balcony
1.2.1 Restroom
1.2.1.1 TP
1.3 Mezzanine
1.3.1 Dungeon
1.3.1.1 Whip
1.13 Secret/Hidden Floor
1.13.4 c:\room
1.13.4.1 Site-to-site VPN for 1.1.1.1
2 Chicago
2.1 Roof
2.1.3 Pidgeon Nest
2.1.3.1 Weathervane我设想的数据结构类似于:
Building = {
1 : 'Central Park',
2 : 'Chicago'
}
Floor = {
1 : {
1 : 'Ground',
2 : 'Balcony',
3 : 'Mezzanine',
13: 'Secret/Hidden Floor'
},
2 : {
1 : 'Roof'
}
}
Room = {
1 : {
1 : {
1 : 'Admin Office',
2 : 'Machine Closet'
}
2 : {
1 : 'Restroom'
}
3 : {
1 : 'Dungeon'
}
... Hopefully by now you get the idea.我的复杂之处在于,我不知道这是否是表示数据的最佳方式,然后将其迭代为:
for buildingID in buildings:
for floorID in floors[buildingID]:
for roomID in rooms[buildingID][floorID]:
for resource in resources[buildingID][floorID][roomID]:
do stuff...或者,如果有一种更理智的方式来用脚本来表示数据,但我需要完整的文档标题编号和名称,这是我能够在我的技能水平上可视化的唯一方法。
我也无法找到一种有效的方法来生成这些信息,并以这种格式从CSV构建到数据结构中。
对一些人来说,这似乎是微不足道的,但我并不是一个职业程序员,实际上我只是偶尔涉足一下。
我的最终目标是能够将CSV吸收到一个正常的数据结构中,按照升序对其进行适当的排序,在上面显示的文本结构中生成行条目,其中只列出每一栋建筑、楼层、房间和资源,并在彼此之间列出,然后表面上我处理文本输出或返回排序CSV将是微不足道的。
如有任何建议,将不胜感激。
编辑:解决方案
利用我下面接受的答案,我能够生成以下代码。谢谢你删除了他的答案和评论,简化了我的排序过程!
import csv
def getPaddedKey(line):
keyparts = line[0].split(".")
keyparts = map(lambda x: x.rjust(5, '0'), keyparts)
return '.'.join(keyparts)
def outSortedCSV(reader):
with open(fOutName, 'w') as fOut:
writer = csv.writer(fOut, delimiter=',')
head = next(reader)
writer.writerow(head)
writer.writerows(sorted(reader, key=getPaddedKey))
s = set()
fInName = 'fIn.csv'
fOutName = 'fOut.csv'
with open(fInName, 'r') as fIn:
reader = csv.reader(fIn, delimiter=',')
outSortedCSV(reader)
fIn.seek(0)
next(fIn)
for row in reader:
ids = row[0].split('.') # split the id
for i in range(1, 5):
s.add(('.'.join(ids[:i]), row[i])) # add a tuple with initial part of id and name
for e in sorted(list(s), key=getPaddedKey):
print e[0] + ' ' + e[1]发布于 2017-07-19 16:11:16
如果您没有理由构建您建议的结构,您可以简单地为每一行添加建筑物、楼层、房间和资源以及它的id到一个集合(以自动消除重复)。然后将集合转换为列表,对其进行排序,您就完成了。
可能的Python代码,假设rd是清单(*)上的csv.reader:
next(rd) # skip the headers line
s = set()
for row in rd:
ids = row[0].split('.') # split the id
for i in range(1, 5):
s.add(('.'.join(ids[:i]), row[i])) # add a tuple with initial part of id and name
l = list(s) # convert to a list
l.sort() # sort it现在您有了一个2元组[('1', 'Central Park'), ('1.1', 'Ground'), ('1.1.1', 'Admin Office'), ...]的列表,您可以使用它构建一个新的csv,或者将它打印为文本:
for i in l:
print(" ".join(i))(*)在Python 3中,您可以使用:
with open(inventory_path, newline = '') as fd:
rd = csv.reader(fd)
...在Python 2中,应该是:
with open(inventory_path, "rb") as fd:
rd = csv.reader(fd)
...发布于 2017-07-19 15:03:48
提取身份证
ids = ['Building_id', 'Floor_id', 'Room_id', 'Resource_id']
labels = ['ResID', 'Building', 'Floor', 'Room', 'Resource']
df2 = df.join(pd.DataFrame(list(df['ResID'].str.split('.')), columns=ids))df2
ResID Building Floor Room Resource Building_id Floor_id Room_id Resource_id
0 1.1.1.1 Central Park Ground Admin Office Router 1 1 1 1
1 1.1.2.1 Central Park Ground Machine Closet Router 1 1 2 1
2 1.3.1.1 Central Park Mezzanine Dungeon Whip 1 3 1 1
3 2.1.3.1 Chicago Roof Pidgeon Nest Weathervane 2 1 3 1
4 1.13.4.1 Central Park Secret/Hidden Floor c:\room Site-to-site VPN for 1.1.1.1 1 13 4 1
5 1.2.1.1 Central Park Balcony Restroom TP 1 2 1 1迭代这个
小辅助法
def pop_list(list_):
while list_:
yield list_[-1], list_.copy()
list_.pop()
for (id_, remaining_ids), (label, remaining_labels) in zip(pop_list(ids), pop_list(labels)):
print(label, ': ', df2.groupby(remaining_ids)[label].first())返回
Resource : Building_id Floor_id Room_id Resource_id
1 1 1 1 Router
2 1 Router
13 4 1 Site-to-site VPN for 1.1.1.1
2 1 1 TP
3 1 1 Whip
2 1 3 1 Weathervane
Name: Resource, dtype: object
Room : Building_id Floor_id Room_id
1 1 1 Admin Office
2 Machine Closet
13 4 c:\room
2 1 Restroom
3 1 Dungeon
2 1 3 Pidgeon Nest
Name: Room, dtype: object
Floor : Building_id Floor_id
1 1 Ground
13 Secret/Hidden Floor
2 Balcony
3 Mezzanine
2 1 Roof
Name: Floor, dtype: object
Building : Building_id
1 Central Park
2 Chicago
Name: Building, dtype: object解释
for (id_, remaining_ids), (label, remaining_labels) in zip(pop_list(ids), pop_list(labels)):
print((id_, remaining_ids), (label, remaining_labels))返回
('Resource_id', ['Building_id', 'Floor_id', 'Room_id', 'Resource_id']) ('Resource', ['ResID', 'Building', 'Floor', 'Room', 'Resource'])
('Room_id', ['Building_id', 'Floor_id', 'Room_id']) ('Room', ['ResID', 'Building', 'Floor', 'Room'])
('Floor_id', ['Building_id', 'Floor_id']) ('Floor', ['ResID', 'Building', 'Floor'])
('Building_id', ['Building_id']) ('Building', ['ResID', 'Building'])因此,这只是在你的建筑结构中的不同层次上迭代。
res = df2.groupby(remaining_ids)[label].first()在您的结构中每个级别构建一个表示此级别上的项的DataFrame,并将嵌套的ID索引到这个级别。这是您想要的最终数据结构的信息,只需将其转换为嵌套的dict。
Building_id Floor_id
1 1 Ground
13 Secret/Hidden Floor
2 Balcony
3 Mezzanine
2 1 Roof发短信(没有嵌套)
res.index = res.index.to_series().apply('.'.join)
print(res)1.1地面1.13秘密/隐蔽楼层1.2阳台1.3夹层2.1屋顶名称:楼层,dtype:物体
https://stackoverflow.com/questions/45193210
复制相似问题