2017-03-24 1 views
0

CSVファイルをボトムアップから読み込み、データをテキストファイルに書き込む必要があります。このファイルには、顧客、製品、場所のさまざまな組み合わせに関する情報があります。ただし、必要な情報がすべて含まれているわけではありません。行が見つからない場合は、数量は0です。このファイルは膨大なものになる可能性があります。そのため、私はそれを書き直したり、追加のリストを使用したりする必要はありません。csvファイルを逆順に読み込んでいる間に前の行を読む

私がしたいのは、ファイルを逆方向​​に読み取っている間に、必要なものをPeriod_idsと私のリストからcsvファイルの各組み合わせのすべてのIDと比較して、IDがない場合は前の行ファイルからのidがリストの要求されたidと同じになるまで(ps。私はforループではできませんが、逆の順序でファイルを読み込む方法がわかりません。私がしなければならないことをする)。所与のデータと必要な結果(緑色は各組み合わせの開始点)を添付した画像を参照してください。下のメソッド(私はこの例では短くしました)は正確には正しくありません。なぜなら、csvファイルからすべての行を取得しますが、欠落している行はないからです。このロジックの助けを借りてありがとうございます(私はまた、パンダのようなライブラリを使わずに何らかの形でこの既存のメソッドを変更することを好むでしょう:)ありがとう!

デフ)(read_file_in_reverse: #...いくつかのコード

# Required ids. 
all_required_ids = [412, 411, 410, 409, 408, 407, 406, 405] 

# Needed to count period ids. 
count_index_for_periodid = 0 

# Read csv file. 
with open(('.\myFile.csv'), 'rb') as f:  
    time_csv = csv.reader(f) 

    # Read the file in reversed order. 
    for line in reversed(list(time_csv)): 
     # ... some code 

      ###### Get quantities from the file. 
      for col_num in range(5, 7): 
       # ... code to get items 

       ### quantity 
       # If next id is not equal to the next required id. 
       if str(next_id) != str(all_required_ids[count_index_for_periodid]): 
        list_qty.append(0) 
       else: 
        qty = line[col_num] 
        list_quantity.append(qty) 

     # Should add another condition here  
     count_index_for_periodid += 1 

enter image description here

+0

スプレッドシートのスクリーンショットではなく、例csvsをここに貼り付けることはできますか?また、それはかなりのコードです。あなたはそれを重要な部分だけを扱っている例に託すことができますか?良いものに行くために沼を歩き回る必要はありません。 – tdelaney

+0

ありがとう、コードを更新しました。しかし、私のファイルをホストに挿入することに問題があります。 –

答えて

0

ファイルが大きい場合、それは時にメモリにファイル全体を読んですることを避けるために最善だろうこれは、ファイルを逆方向​​に読み取る必要がある場合に必要になります。代わりに、問題を再考して、ファイル転送を解析してください。実際には、必要なすべてを含む行のブロックを書き込もうとしています。Period_id。したがって、前の行にID < =の行が見つかるまで、行の読み取りを続けます。この時点でブロックがあり、欠落している行を含むように展開してからファイルに書き込む必要があります。たとえば、次のブロックのために見つかったすべてのエントリを取得し、IDに基づいて辞書に変換することにより、

import csv 

def write_block(block): 
    if len(block): 
     fill = block[0][1:4] 
     block_dict = {int(row[4]) : row for row in block} 

     for row in range(405, 413): 
      try: 
       csv_output.writerow(block_dict[row]) 
      except KeyError as e: 
       csv_output.writerow([999] + fill + [row, 0, 0, 0]) 

with open('myFile.csv', 'rb') as f_input, open('output.csv', 'wb') as f_output: 
    csv_input = csv.reader(f_input) 
    csv_output = csv.writer(f_output) 
    header = next(csv_input) 
    csv_output.writerow(header) 
    block = [next(csv_input)] 

    for row in csv_input: 
     # Is the period ID <= to the last one that was read? 
     if int(row[4]) <= int(block[-1][4]): 
      write_block(block) 
      # Start a new block 
      block = [row] 
     else: 
      block.append(row) 

    # Write any remaining entries when the end of file is reached 
    write_block(block) 

write_block()作品。次に、辞書に必要な各IDを検索しようとします。存在する場合は、そのまま出力ファイルに書き込まれます。それが欠落している場合は、他の値を使用して適切な行が作成されます。


あなたが本当に後方で作業したい場合は、単純に(使用してリスト(csv_input))でファイル全体を読み込み、[::-1]を使用して、後方のエントリを反復処理します。その後、ロジックを変更して、前の行を読み取るID >=を探します。例えば

import csv 

def write_block(block): 
    if len(block): 
     fill = block[0][1:4] 
     block_dict = {int(row[4]) : row for row in block} 

     for row in range(405, 413): 
      try: 
       csv_output.writerow(block_dict[row]) 
      except KeyError as e: 
       csv_output.writerow([999] + fill + [row, 0, 0, 0]) 

with open('myFile.csv', 'rb') as f_input, open('output.csv', 'wb') as f_output: 
    csv_input = csv.reader(f_input) 
    csv_output = csv.writer(f_output) 
    header = next(csv_input) 
    csv_output.writerow(header) 
    block = [next(csv_input)] 

    for row in list(csv_input)[::-1]: 
     if int(row[4]) >= int(block[-1][4]): 
      write_block(block) 
      block = [row] 
     else: 
      block.append(row) 

    write_block(block) 

あなたはfor文の後print rowを追加する場合は、それが逆方向に働いていることを確認することができるだろう。

+0

ああ、今、私は小さなファイルで作業しているので、ファイルを逆方向​​に読み込んでいる間にメモリの問題を忘れていました。ありがとうございました! –

+0

確かに、この練習では重要ではありませんが、大きな問題を扱うときには覚えておくと便利です。私は同じコードを使用してファイルを後方に解析する方法を示すように更新しました。 –

+0

ありがとう、あなたの例は本当に役立ちます!特に私は物事の束を読んで、私の場合に適した何かを見ていないとして、後ろのもの。 –

関連する問題