长时间潜伏,第一次海报..
我有一个非常大的文本文件(1,184,834行),其中包含有关欧洲特定日期的航班计划的一些信息。每列代表一个新密钥,每一行都是该航班的新段。到目前为止,我已设法使用以下代码将我分析所需的数据提取到列表列表中:
import pprint
import csv
pp = pprint.PrettyPrinter(width=200)
text = open('E:/Downloads/TNFL09/20120506_m1.so6', 'r')
def clean_data(text, rows):
newlist = []
reader = list(csv.reader(text, delimiter=' '))
for n in xrange(0, len(reader)):
newlist.append(reader[n][1:6]+reader[n][9:12]+reader[n][16:18])
return newlist[:rows]
data = clean_data(text,90)
pp.pprint(data)
输出如下:
['UAFM', 'EGKK', 'A333', '083914', '084141', 'CMB595', '120506', '120506', '156912756', '91'],
['KEWR', 'VABB', 'B772', '005500', '010051', 'UAL48', '120506', '120506', '156912546', '1']
['KEWR', 'VABB', 'B772', '010051', '010310', 'UAL48', '120506', '120506', '156912546', '2']
此问题的有趣项目是开始/结束时间(#3&#4),航班ID(#8)和序列号(#9)。
每个航班都包含多个连续的序列号。因此,要获得整个航班,必须提取该航班ID的所有序列号。
我想做的事情是提取每次航班的开始和结束时间。我最初的思路是循环遍历列表中的每个列表,并将序列号与先前迭代的列表进行比较。但是我是Python的初学者,经过几天的谷歌搜索后放弃了。
谢谢,
彼得
答案 0 :(得分:0)
一种方法,假设您的列表列表按序列号排序(看起来像它们)是通过生成器运行它来聚合每个航班:
def aggregate_flights(flights):
out = []
last_id = ''
for row in flights:
if row[-2] != last_id and len(out) > 0:
yield (last_id,out)
out = []
last_id = row[-2]
out.append((row[3],row[4])) #2-tuple of (start,end)
yield (last_id,out)
这给出了您的示例输入:
list(aggregate_flight(agg))
Out[21]:
[('156912756', [('083914', '084141')]),
('156912546', [('005500', '010051'), ('010051', '010310')])]
有点乱,但你明白了。对于每个航班,您将获得(start,end)
的2元组列表,您可以对其进行进一步处理以获得该航班的整体(start,end)
。您甚至可以将生成器修改为只是为您提供整体(start,end)
,但我倾向于使用易于调试的较小的模块化块进行处理。
如果您的输入未已排序,则需要使用defaultdict
累积数据。给它一个list
工厂并为每一行添加(start,end)
元组。
编辑,这里的修改只为每个航班产生一对(start,end)
:
def aggregate_flights(flights):
last_id,start,end = None,None,None
for row in flights:
if row[-2] != last_id and last_id is not None:
yield (last_id,(start,end))
start,end = None,None
if start is None:
start = row[3]
last_id = row[-2]
end = row[4]
yield (last_id,(start,end))
此时我注意到输出太难看了(一个(id,(start,end))
元组,呃)所以我要升级到namedtuple
以使事情变得更好:
from collections import namedtuple
Flight = namedtuple('Flight',['id','start','end'])
所以现在你有:
def aggregate_flights(flights):
last_id,start,end = None,None,None
for row in flights:
if row[-2] != last_id and last_id is not None:
yield Flight(last_id,start,end)
start,end = None,None
if start is None:
start = row[3]
last_id = row[-2]
end = row[4]
yield Flight(last_id,start,end)
list(aggregate_flights(agg))
Out[18]:
[Flight(id='156912756', start='083914', end='084141'),
Flight(id='156912546', start='005500', end='010310')]
好多了。
答案 1 :(得分:0)
我无法确定您的列表是否已按航班ID和序列号排序,为此您可以在列表清单中执行以下操作:
from operator import itemgetter
#use sort if the original list is not necessary to maintain,
#if it is use sorted and send it to a new variable
flightInfo.sort(key = itemgetter(8,9))
以上按航班号排序,然后按序号排序。要提取你想要的东西,你可以这样做:
prev, startTime = None, None
results = []
for i, info in enumerate(flightInfo):
if prev == None or prev != flight[8]:
if prev != None:
# use a list if you are going to have to modify these values
results.append((prev, startTime, flightInfo[i-1][4]))
startTime = flight[3]
prev = flight[8]
答案 2 :(得分:0)
您可以使用map关键字。成为“full_list”的航班列表:
# python.py
time = [] # Is a dictionaries list. Each dictionary contains: {flight_id: [start, end]}
result = [] # We going to store results here.
def extract(flight, result):
""" param flight: list containing flight's data. """
global result # Give function access to result variable.
# If not, "result" is passed as a value copy.
result.append({flight[9]: [flight[3], flight[3]]})
map(extract, result)
那应该做的工作。