【问题标题】:Python CSV writer automatically limit rows per file and create new filesPython CSV 编写器自动限制每个文件的行数并创建新文件
【发布时间】:2018-05-12 05:32:59
【问题描述】:

我正在编写一个将大量数据写入.csv 文件的脚本。为了使感兴趣的用户之间的数据传输更容易,我想对每个文件的行数进行限制。例如,我希望将第一百万条记录写入some_csv_file_1.csv,将第二百万条记录写入some_csv_file_2.csv,依此类推,直到所有记录都写入为止。

我试图让以下工作:

import csv
csv_record_counter = 1
csv_file_counter = 1

while csv_record_counter <= 1000000:
    with open('some_csv_file_' + str(csv_file_counter) + '.csv', 'w') as csvfile:
        output_writer = csv.writer(csvfile, lineterminator = "\n")
        output_writer.writerow(['record'])
        csv_record_counter += 1
while not csv_record_counter <= 1000000:
    csv_record_counter = 1
    csv_file_counter += 1

问题:当记录增加到超过 1000000 时,不会创建后续文件。该脚本继续将记录添加到原始文件中。

【问题讨论】:

  • 你试过用羽毛包吗?
  • 我没听说过羽毛
  • ['record'] 来自哪里?它看起来像什么 [['record'], .....]?
  • 每条记录都是从包含千万条记录的数据流中获取的。

标签: python csv


【解决方案1】:

首先缩进你的第二个while循环并删除“not”。 然后使用 for- 而不是 while 循环来创建你的 csvs。 此外,不要忘记重置您的 csv_record_counter。

import csv
csv_record_counter = 1

rows = #Your number of rows to process

additional_file = 1 if rows/1000000 % 2 != 0 else 0

for csv_file in range(1, int(rows/1000000) + 1 + additional_file): #Set rows as your maximum number of rows / This will return your number of csv to create
    with open('some_csv_file_' + str(csv_file) + '.csv', 'w') as csvfile:
        output_writer = csv.writer(csvfile, lineterminator = "\n")
        output_writer.writerow(['record'])
        csv_record_counter = 1 #Remove your "+"
        while csv_record_counter <= 1000000: #Remove your "not"
            csv_record_counter += 1
            output_writer.writerow("your record")

编辑:添加了附加文件

【讨论】:

    【解决方案2】:

    我喜欢在导出数据之前对其进行批处理。

    def batch(iterable, n=1):
        length = len(iterable)
        for ndx in range(0, length, n):
            yield iterable[ndx:min(ndx + n, length)]
    
    headers = []  # Your headers
    products = []  # Milions of products go here
    batch_size = int(len(db_products) / 4)  # Example
    # OR in your case, batch_size = 1000000000
    
    for idx, product_batch in enumerate(batch(products, batch_size)):
        with open('products_{}.csv'.format(idx + 1), 'w') as csvfile:
            writer = csv.DictWriter(csvfile, fieldnames=headers)
            writer.writeheader()
            for product in product_batch:     
                writer.writerow(product)   
    

    参考资料:

    【讨论】:

      【解决方案3】:

      在使用writer.writerow()后尝试writefile.flush()

      该刷新语句将清除缓冲区,使内存可以腾出以完成新任务。

      在处理大量行时,缓冲区将被任务填满,并且在您当前运行的代码退出之前不会被清除。

      因此,每次使用 write 语句在文件中写入内容时,最好手动清除缓冲区

      【讨论】:

      • 这个答案出现在 SO.. 的低质量帖子中。你能在你的答案中添加任何评论吗?解释你的逻辑,并对你的代码打算做什么做一点评论。这将有助于 OP,但它也将作为未来用户的评论
      【解决方案4】:

      我认为您的数据传输可以通过上述课程成功:

      import csv
      
      class Writer:
          def __init__(self, max_row):
              self.max_row = max_row
              self.cur_row = 0
              self.file_number = 0
              self.file_handle = None
      
          def write_row(self, row):
              if self.cur_row >= self.max_row or self.file_handle == None:
                  self.cur_row = 0
                  self.file_number += 1
      
                  if self.file_handle:
                      self.file_handle.close()
      
                  self.file_handle = open(f'some_csv_file_{self.file_number}.csv', 'w', newline='')
                  self.csv_handle = csv.writer(self.file_handle)
      
              self.csv_handle.writerow(row)
              self.cur_row += 1
      
      
      writer = Writer(10) # 1000000 for you
      
      for row in range(55): # massive amount of data
          output_row = [row+1, "record1", "record2"]
          writer.write_row(output_row)
      

      在示例中,每个文件(some_csv_file_1.csvsome_csv_file_2.csv、...)当前正在生成 10 条记录。

      输出:

      为你:

      output_writer = Writer(1000000)
      output_writer.write_row(['record'])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-24
        • 1970-01-01
        • 1970-01-01
        • 2016-08-11
        • 2023-03-13
        • 2021-02-07
        • 1970-01-01
        • 2022-01-06
        相关资源
        最近更新 更多