【问题标题】:Python: CSV write by column rather than rowPython:CSV按列而不是按行写入
【发布时间】:2011-05-08 11:50:48
【问题描述】:

我有一个 python 脚本,它在一个 while 循环中生成一堆数据。我需要将此数据写入 CSV 文件,因此它按列而不是按行写入。

例如在我生成的脚本的循环 1 中:

(1, 2, 3, 4)

我需要这样在我的 csv 脚本中反映出来:

Result_1    1
Result_2    2
Result_3    3
Result_4    4

在我的第二个循环中,我生成:

(5, 6, 7, 8)

我需要这个来查看我的 csv 文件,如下所示:

Result_1    1    5
Result_2    2    6
Result_3    3    7
Result_4    4    8

以此类推,直到 while 循环结束。有人可以帮帮我吗?


编辑

while 循环可以持续超过 100,000 次循环

【问题讨论】:

  • “while 循环”、“loop 1”、“second loop”——都相当模糊。输出文件中有多少行?输出文件有多少列?
  • 嗨。您是否找到了一种无需 cretin 中间变量的方法?

标签: python csv


【解决方案1】:

csv 不支持的原因是因为大多数文件系统并不真正支持可变长度行。你应该做的是收集列表中的所有数据,然后在它们上调用zip() 以在之后转置它们。

>>> l = [('Result_1', 'Result_2', 'Result_3', 'Result_4'), (1, 2, 3, 4), (5, 6, 7, 8)]
>>> zip(*l)
[('Result_1', 1, 5), ('Result_2', 2, 6), ('Result_3', 3, 7), ('Result_4', 4, 8)]

【讨论】:

  • 问题是 while 循环可以持续超过 100,000 个循环或更多。这将使列表变得非常大。
  • @Harpal:这是问题的重要部分。请编辑您的问题以包含此内容。
  • 请记住,Excel 至少有一个最大行数和行数,如果超过,打开文件时不会显示数据,如果保存,数据将被丢弃,至少这个发生在我的案例中。
【解决方案2】:
wr.writerow(item)  #column by column
wr.writerows(item) #row by row

如果您的目标只是逐列编写输出,这非常简单。

如果您的项目是列表:

yourList = []

with open('yourNewFileName.csv', 'w', ) as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    for word in yourList:
        wr.writerow([word])

【讨论】:

  • zip() 很棒,但writerow() 是真正的交易!
【解决方案3】:

大多数文件系统不支持更新文件中的行(文件中的一行只是一些以换行符结尾的数据,下一行紧随其后开始)。

在我看来,您有两个选择:

  1. 让您的数据生成循环成为生成器,这样它们就不会消耗大量内存 - 您将“及时”获取每一行的数据
  2. 使用数据库(sqlite?)并更新那里的行。完成后 - 导出为 CSV

第一种方法的小例子:

from itertools import islice, izip, count
print list(islice(izip(count(1), count(2), count(3)), 10))

这将打印出来

[(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7), (6, 7, 8), (7, 8, 9), (8, 9, 10), (9, 10, 11), (10, 11, 12)]

即使count 生成无限的数字序列

【讨论】:

    【解决方案4】:

    Result_* 呢?循环中也有生成(因为我认为不可能添加到 csv 文件中)

    我会这样;一次生成所有数据旋转矩阵写入文件:

    A = []
    
    A.append(range(1, 5))  # an Example of you first loop
    
    A.append(range(5, 9))  # an Example of you second loop
    
    data_to_write = zip(*A)
    
    # then you can write now row by row
    

    【讨论】:

      【解决方案5】:

      假设 (1) 您没有大内存 (2) 您在列表中有行标题 (3) 所有数据值都是浮点数;如果它们都是 32 位或 64 位的整数,那就更好了。

      在 32 位 Python 上,将浮点数存储在列表中需要 16 个字节用于浮点对象,4 个字节用于列表中的指针;总共 20 个。在 array.array('d') 中存储一个浮点数只需要 8 个字节。如果您的所有数据都是 int(是否为负数?),可以容纳 8、4、2 或 1 个字节,那么可以节省越来越多的费用——尤其是在最近的 Python 中,所有 int 都是长整数。

      以下伪代码假定浮点数存储在 array.array('d') 中。如果你真的没有内存问题,你仍然可以使用这个方法;如果您想使用列表,我已放入 cmets 以指示所需的更改。

      # Preliminary:
      import array # list: delete
      hlist = []
      dlist = []
      for each row: 
          hlist.append(some_heading_string)
          dlist.append(array.array('d')) # list: dlist.append([])
      # generate data
      col_index = -1
      for each column:
          col_index += 1
          for row_index in xrange(len(hlist)):
              v = calculated_data_value(row_index, colindex)
              dlist[row_index].append(v)
      # write to csv file
      for row_index in xrange(len(hlist)):
          row = [hlist[row_index]]
          row.extend(dlist[row_index])
          csv_writer.writerow(row)
      

      【讨论】:

        【解决方案6】:

        逐行读取,然后在命令行中转置。如果您使用的是 Unix,请安装 csvtool 并按照以下说明进行操作:https://unix.stackexchange.com/a/314482/186237

        【讨论】:

          【解决方案7】:

          作为另一种流式传输方法:

          • 将每个列转储到一个文件中
          • 使用 python 或 unix paste 命令重新加入选项卡、csv 等。

          这两个步骤都可以很好地处理蒸汽。

          陷阱:

          • 如果您有 1000 列,您可能会遇到 unix 文件句柄限制!

          【讨论】:

            【解决方案8】:

            经过一段时间的思考,我想出了一个更简单的方法来实现相同的目标。假设你有如下代码:

            fruitList = ["Mango", "Apple", "Guava", "Grape", "Orange"]
            vegList = ["Onion", "Garlic", "Shallot", "Pumpkin", "Potato"]
            with open("NEWFILE.csv", "w") as csvfile:
                writer = csv.writer(csvfile)
                for value in range(len(fruitList)):
                    writer.writerow([fruitList[value], vegList[value]])
            

            【讨论】:

              【解决方案9】:

              zip 只会采用等于最短长度列表的元素数。如果您的列长度相等,则需要使用zip_longest

              import csv
              from itertools import zip_longest
              
              data = [[1,2,3,4],[5,6]]
              columns_data = zip_longest(*data)
              
              with open("file.csv","w") as f:
                  writer = csv.writer(f)
                  writer.writerows(columns_data)
              

              【讨论】:

                【解决方案10】:

                fruitList = [“芒果”、“苹果”、“番石榴”、“葡萄”、“橙子”] vegList = [“洋葱”、“大蒜”、“青葱”、“南瓜”、“土豆”]

                【讨论】:

                • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
                猜你喜欢
                • 2015-04-24
                • 1970-01-01
                • 2018-08-10
                • 1970-01-01
                • 1970-01-01
                • 2015-09-08
                • 2021-11-01
                • 1970-01-01
                相关资源
                最近更新 更多