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

1 つの方法は、リストのリストがシーケンス番号でソートされていると仮定して (そうであるように見えます)、ジェネレーターを実行して各フライトをまとめることです。

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)フライトごとに 1 つのペアのみを生成するための変更を次に示します。

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物事をより良くするために a に移動します:

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

あなたのリストがすでにフライト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 に答える