在python中迭代创建csv的有效方法

时间:2018-04-10 21:03:11

标签: python csv

假设我有100,000个用户。我想创建一个包含100,000行和K列的csv文件。 K预计将在几百左右。每行包含一个用户的数据,每列是一个变量。我使用for循环创建了这样的csv数据,其中每次迭代构造一个字典,其键是变量名。如果我知道K变量名称,我可以使用csv.DictWriter追加新行。

问题是我不知道变量'名称或数字K. 一种方法是使用pandas.DataFrame.append函数。我不喜欢这个,因为pandas'文档说append迭代追加的速度很慢。我无法在某处使用loc,因为列数会有所不同。

我目前的策略是创建三个listlist1是存储变量名称; list2是为了保存价值;而list3是保存行索引。循环中的python中的追加列表很容易。 从list3开始,我创建了一个唯一行索引列表,这些索引将用作csv的字段名称。对于每个变量,我创建一个字典,其键是行索引,相应的值是该行中变量的值。然后我使用csv.DictWriter创建csv文件。最后一步是转置创建的csv文件。

我很高兴听到改进建议。

# Example: three rows (r1, r2, r3) and four variables (n1, n2, n3, n4)
list1 = ['n1', 'n2', 'n3', 'n2', 'n3', 'n3', 'n4']    # n* is variable name
list2 = ['v11', 'v12', 'v13', 'v22', 'v23', 'v33', 'v34']    # v* is value
list3 = ['r1', 'r1', 'r1', 'r2', 'r2', 'r3', 'r3']    # v* is row id
# Convert to data of the following format
# n1  n2  n3  n4
# v11 v12 v13 NA
# NA  v22 v23 NA
# NA  NA  v33 v34

# MY CURRENT WORKFLOW:
# 1. create a list of unique row id
from collections import OrderedDict
rowIds = list(OrderedDict.fromkeys(list3))  # this preserve row id order
# 2. create a list of unique variable names
names = list(OrderedDict.fromkeys(list1))
# 3. For each variable n*, create a dictionary whose keys are row id, and
# whose values are values of the variable in the row of the row id in the
# key.
import csv
with open('example.csv', 'w', newline='') as csvfile:
    # use rowIds as fieldname for DictWriter
    fieldnames = rowIds
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    for name in names:
        index = [i for i, x in enumerate(list1) if x == name]
        dict1 = {list3[i]: list2[i] for i in index}
        writer.writerow(dict1)
# Transpose row-to-column and use 'names' as the new header. There are
# plenty ways to do this.

1 个答案:

答案 0 :(得分:0)

您应该能够构建每一行,直到行ID的更改如下所示:

import csv

list1 = ['n1', 'n2', 'n3', 'n2', 'n3', 'n3', 'n4']
list2 = ['v11', 'v12', 'v13', 'v22', 'v23', 'v33', 'v34']
list3 = ['r1', 'r1', 'r1', 'r2', 'r2', 'r3', 'r3']

header = sorted(set(list1))     # Build a list of column names

with open('output.csv', 'w', newline='') as f_output:
    csv_output = csv.DictWriter(f_output, fieldnames=header, restval='NA')
    csv_output.writeheader()
    row = {}
    cur_row = list3[0]

    for v1, v2, v3 in zip(list1, list2, list3):
        if cur_row == v3:
            row[v1] = v2
        else:
            csv_output.writerow(row)
            row = {v1 : v2}
            cur_row = v3

    csv_output.writerow(row)

为您提供包含以下内容的output.csv文件:

n1,n2,n3,n4
v11,v12,v13,NA
NA,v22,v23,NA
NA,NA,v33,v34