0

コード(以下に再現)は、ファイルを読み込み、処理を実行し、元のファイルのサブセットを新しいファイルに出力します。少し調整して、代わりに、初期ファイルから出力ファイルまですべてを出力しますが、値が「1」の「フラグ」列を追加します。この行は、現在出力される行です(私たちが最も興味を持っている行のサブセット)?他の行(現在は入力ファイルのみにある行)には、新しい「フラグ」列に空白または「0」があります。

この問題は私にとって十分頻繁に発生するので、これを行う一般的な方法を用意するだけで何時間も節約できます。

助けていただければ幸いです。

import csv
inname = "aliases.csv"
outname = "output.csv"

def first_word(value):
    return value.split(" ", 1)[0]

with open(inname, "r", encoding = "utf-8") as infile:
    with open(outname, "w", encoding = "utf-8") as outfile:
      in_csv = csv.reader(infile)
      out_csv = csv.writer(outfile)

      column_names = next(in_csv)
      out_csv.writerow(column_names)

      id_index = column_names.index("id")
      name_index = column_names.index("name")

      try:
          row_1 = next(in_csv)
          written_row = False

          for row_2 in in_csv:
              if first_word(row_1[name_index]) == first_word(row_2[name_index]) and row_1[id_index] != row_2[id_index]:
                  if not written_row:
                      out_csv.writerow(row_1)

                  out_csv.writerow(row_2)
                  written_row = True
              else:
                  written_row = False

              row_1 = row_2
      except StopIteration:
          # No data rows!
          pass
4

1 に答える 1

0

私は CSV を書くときは常に DictReader を使用します。これは主に、もう少し明示的であるためです (これにより、作業が簡単になります:))。以下は、あなたができることの高度に様式化されたバージョンです。私が行った変更は次のとおりです。

  • csv.DictReader()csv.DictWriter()の代わりにcsv.readerとを使用しcsv.writerます。これは、リストの代わりに辞書を使用して行を表すという点で異なります。つまり、行は のようになります{'column_name': 'value', 'column_name_2': 'value2'}。これは、すべての行に列ヘッダー データが含まれ、辞書のように扱うこともできることを意味します。
  • サンプル列名を使用して、読み取り/書き込みがどのように機能するかを示します。と の 2 つの列を持つサンプル CSV を作成し、書き込み時に、name値がnumbernumber> 2

それを念頭に置いて、例を次に示します。

import csv

input_csv = 'aliases.csv'
output_csv = 'output.csv'

def first_word(value):
    return value.split(' ', 1)[0]

with open(input_csv, 'r') as infile:
    # Specify the fieldnames in your aliases CSV
    input_fields = ('name', 'number')

    # Set up the DictReader, which will read the file into an iterable
    # where each row is a {column_name: value} dictionary
    reader = csv.DictReader(infile, fieldnames=input_fields)

    # Now open the output file
    with open(output_csv, 'w') as outfile:
        # Define the new 'flag' field
        output_fields = ('name', 'number', 'flag')
        writer = csv.DictWriter(outfile, fieldnames=output_fields)

        # Write the column names (this is a handy convention seen elsewhere on SO)
        writer.writerow(dict((h, h) for h in output_fields))

        # Skip the first row (which is the column headers) and then store the
        # first row dictionary
        next(reader)
        first_row = next(reader)

        # Now begin your iteration through the input, writing all fields as they
        # appear, but using some logic to write the 'flag' field
        # This is where the dictionary comes into play - 'row' is actually a
        # dictionary, so you can use dictionary syntax to assign to it
        for next_row in reader:
            # Set up the variables for your comparison
            first_name = first_word(first_row['name'])
            next_name = first_word(next_row['name'])
            first_id = first_row['number']
            next_id = next_row['number']

            # Compare the current row to the previous row
            if first_name == next_name and first_id != next_id:
                # Here we are adding an element to our row dictionary - 'flag'
                first_row['flag'] = 'Y'
            # Now we write the entire first_row dictionary to the row
            writer.writerow(first_row)

            # Change the reference, just like you did
            first_row = next_row
于 2012-08-11T00:07:08.803 に答える