1

长期潜伏者,第一次海报..

我有一个非常大的文本文件(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 的初学者,经过几天的谷歌搜索后放弃了。

谢谢,

彼得

4

3 回答 3

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')])]

有点乱,但你明白了。对于每个航班,您将有一个 2 元组列表,(start,end)您可以进一步处理这些列表以获得该(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))元组,呃),所以我会升级到 anamedtuple以使事情变得更好:

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')]

好多了。

于 2013-11-01T17:49:55.063 回答
0

您可以使用地图关键字。作为“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)

那应该做的工作。

于 2013-11-01T17:58:46.943 回答
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]
于 2013-11-01T17:51:00.493 回答