2011-07-25 8 views
0

私は一緒に追加して新しいファイルに入れる必要があるファイル名がたくさんあります。最初の列は日付です。日付があるファイルから別のファイルに重複している場合は、私が既に持っているものを置き換えるために追加する次のファイルが必要です。たとえば、最初のファイルのようなものである場合:特定の行を置換し、CSVファイルの残りをPythonで追加する

1/5/2010 'hello' 
1/6/2010 'goodbye' 
1/7/2010 'yes' 

と第二のファイルは以下のとおりです。

1/7/2010 'No' 
1/8/2010 "spam' 
1/9/2010 'today' 

私は私の新しいファイルは次のようになりたい:今

1/5/2010 'hello' 
1/6/2010 'goodbye' 
1/7/2010 'No' 
1/8/2010 'spam' 
1/9/2010 'today' 

私はこのようなことをしようとしていますが、正しい結果を得ていません。

for row in reader2: 
    for row2 in reader: 
     if row == row2: 
      target = open('newfile2.csv', 'wb') 
      writer = csv.writer(target) 
      writer.writerow(row) 
      target.close() 
     else: 
      target = open('newfile2.csv', 'ab') 
      writer = csv.writer(target) 
      writer.writerow(row) 
      target.close() 

任意のアイデアを大幅に理解されるであろう(リーダ2及びリーダはnewfile2.csvは既にファイル1の内容を有し、それぞれ第二のファイルと最初のファイルを参照します)。おかげで さて、私はいくつかのコメントを読んだ後で明確にすべきだと思います。順序は重要です。このコードの最後で、私は毎年1日のデータを整理して欲しいと思います。良いニュースは、データが既にファイル内に整列していることです。重複がいくつかあります。

複数の複製があります。たとえば、私が実際に扱っている最初のファイルは3月9日まで、2月の終わりには止めたいと思っています。 2番目のファイルからすべての3月のデータが必要です。

また、実際のファイルでは1日の1時間も行の一部であるため、約1500以上の行があります。

私は何が必要なのかを明確にしたいと思います。

私は上に掲載したコードのように思えますが、各行の最初の列のみをチェックします(日付は重複しているため)。今は全行をチェックしていますが、日付は重複していますが、行全体は一意です。

ああ、最後の1つです。私はすべての重複を排除したい。

答えて

1

試してみてください。

dictio = {} 
for row in reader: 
    [date, text] = row.split() 
    dictio[date] = text 

for row in reader2: 
    [date, text] = row.split() 
    dictio[date] = text 

target = open('newfile2.csv', 'wb') 
writer = csv.writer(target) 
for date, text in dictio.iteritems(): 
    writer.writerow("%s %s" %(date, text)) 
target.close() 

編集:あなたがアイテムの順序を維持したい場合は、コメントの後、

dictio = {} 

dictio = collections.OrderedDict() 

この作品を変更Python用> 2.6

+0

これは、行の順序をまったく維持しません。また、ファイルの終わりにつながるものだけでなく、すべての重複を排除します。 @ agf、右。 – agf

+0

この点はあなたの質問にはっきりと記載されていませんでした。最後の最初の行だけ? – joaquin

+0

私の質問ではありませんでした。ちょうどそれが、特に注文に関連して、彼が望んでいたことがはっきりしていないと言っていました。 – agf

0

ファイルが膨大ではない場合(何千もの行)、これは入力ファイルの数に関係なく、行順を維持し、指定した重複のみを削除するだけです。

input_files = 'a.csv, b.csv, c.csv, d.csv' 

last = '.' 
# open the outfile and make the csv writer here 
for input_file in input_files: 
    # open the infile and make the csv reader here 
    lines = reader.readlines() 
    # save the last line for later 
    last_new = reader.pop() 
    if last.split()[0] != lines[0].split()[0]: 
     writer.writeln(last) 
    writer.writelines(lines) 
    last = last_new 
    reader.close() 
writer.writeln(last) 
writer.close() 

あなたはすべての重複を取り除きたい場合は、他の回答の一つにdictメソッドを使用しますが、dictを使用していない、({})、collections.OrderedDict()ので、行は順番に滞在使います。

OrderedDict for Python 2.4-2.6の代替案はhttp://pypi.python.org/pypi/ordereddictです。

0

これまでに投稿された回答はすべて、データをメモリに読み込むことに依存していましたが、それは小さな入力ファイルにとっては問題ありません。しかし、入力ファイルがすでにソートされていると言うので、入力ファイルを行ごとに処理することができ、任意の行数のファイルを処理できるようになります。 、出力用のCSV writer、および機能 - あなたは(多くのファイルが同じキーを持つ行が含まれている場合は、最初の読者からの行が取得されます優先順に)csvreadersのリストを持っていると仮定すると

行ごとにソート・キーを抽出するためのkey、あなただけの出力は常に同じキー値を持つすべての読者を最小ソートキー値を含む、あらかじめ行ができます。

def combine(readers, writer, key): 
    rows = [reader.next() for reader in readers] 
    while rows: 
     # select the first input row with the minimum sort key value 
     row = min(rows, key=key) 
     writer.writerow(row) 
     # advance all readers with the minimum sort key value 
     min_key = key(row) 
     for i in xrange(len(readers)): 
      if key(rows[i]) == min_key: 
       try: 
        rows[i] = readers[i].next() 
       except StopIteration: 
        # reader exhausted, remove it 
        del rows[i] 
        del readers[i] 

は、サンプルファイルからソート可能なキーを取得するにはそれはやや厄介な形式なので、日付を解析する必要があります。ファイル内のISO %Y-%m-%d日付を使用すると、自然に並べ替えるので、作業が楽になります。

import datetime 

def key(row): 
    return datetime.datetime.strptime(row[0], '%m/%d/%Y') 

python combine.py input1.csv input2.csv > output.csvを実行することができます。入力ファイルの順序が逆になり、後で指定されたファイルが先に指定されたファイルよりも優先されます。

import csv, sys 

delimiter = ' '       # used in the example input files 
readers = [csv.reader(open(filename), delimiter=delimiter) 
      for filename in reversed(sys.argv[1:])] 
writer = csv.writer(sys.stdout, delimiter=delimiter); 
combine(readers, writer, key) 
関連する問題