输出到CSV:将现有代码改为添加“Flag”列

2024-03-28 09:03:33 发布

您现在位置:Python中文网/ 问答频道 /正文

代码(复制如下)读入一个文件,执行一些操作,并将原始文件的一个子集输出到一个新文件中。我如何稍微调整一下,然后将从初始文件输出到输出文件的所有内容,但是添加一个“flag”列,其中的值为“1”,其中该行是当前要输出的行(我们最感兴趣的行的子集)?其他行(当前仅在输入文件中)的新“flag”列中有一个空白或“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

Tags: 文件csvnameinidindexnamescolumn
1条回答
网友
1楼 · 发布于 2024-03-28 09:03:33

我在编写CSV时总是使用听写器,主要是因为它更显式(这使我更容易:))。下面是一个高度程式化的版本,你可以做什么。我所做的更改包括:

  • 使用^{cd1>}和^{cd2>}代替^{{cd3>}和^{cd4>}。这一点不同于使用字典来表示行而不是列表,这意味着一行看起来像^{{cd5>}。这意味着每一行都包含列头数据,也可以像字典一样处理。
  • 使用示例列名来显示读/写的工作方式。我制作了一个包含两列:^{{cd6>}和^{cd7>}的示例CSV,然后在编写时,我做了一个简单的检查,以查看^{cd7>}值是否为^{cd9>}

考虑到这一点,下面是示例:

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

相关问题 更多 >