使用Python将csv行转换为列

时间:2017-11-23 19:51:50

标签: python file csv row multiple-columns

请问你能帮帮我吗?

我需要转换:

  • 一行,包含多个文件中的多列

TO

  • 一个文件

在哪里

  • 列数等于文件数
  • 并且行数等于输入文件中的列数。

输入文件

文件1: 32676 ;; 90; 5; 22; ...; 4

文件2: 255; 35; 88; 17 ;; ...; 151

文件3: 551; 86; 442 ;; 78; ...; 20

输出文件

32676; 255; 551

; 35; 86

90; 88; 442

5; 17;

22 ;; 78

...; ...; ...

4; 151; 20

非常感谢你的帮助!

My code :

path = 'D:\Users\mim\Desktop\SI\Test_cvs'
pathglobalcsv = 'D:\Users\mim\Desktop\SI'

#create a new file
globalfile = open(os.path.join(pathglobalcsv, 'global.csv'), 'w+')

#write filenames like column names
files = os.listdir(path)
globalfile.write(';'.join(files))
globalfile.write('\n')

#get all values
for filename in glob.glob(os.path.join(path, '*.csv')):
    csvfile = open(filename, 'r')
    textcsv = csv.reader(csvfile, delimiter=';')
    globalfile.write(zip(*textcsv))

I have an error : 

Traceback (most recent call last):
  File "C:\Users\mim\eclipse-workspace\test\csv_global.py", line 86, in <module>
    globalfile.write(zip(*textcsv))
TypeError: expected a string or other character buffer object

1 个答案:

答案 0 :(得分:0)

有关如何使用zip来合并数据以及转置列表的一些提示。 这听起来像是如何转置csv是你的实际问题。如何转换csv的答案是将其转换为列表列表(例如通过csv模块),然后将其转置并写回文件(如果需要)。

row1 = [1,2,3]

row2 = ['a', 'b', 'c']

list(zip(row1, row2))
Out[45]: [(1, 'a'), (2, 'b'), (3, 'c')]

z = list(zip(row1, row2))

list(zip(*z))
Out[47]: [(1, 2, 3), ('a', 'b', 'c')]

y = list(zip(*z))

y
Out[49]: [(1, 2, 3), ('a', 'b', 'c')]

list(zip(*y))
Out[50]: [(1, 'a'), (2, 'b'), (3, 'c')]

或者如果你安装了numpy或pandas,那么这两个代码都将通过工作流read_file / transpose_matrix / write_transposed_to_file

完成最多3行代码的工作。

因此,根据您的代码,我会读取所有文件放入内存,然后进行转置写入。我想如果你改变这个部分就会这样做(我自己没有测试过)。

#write filenames like column names
files = os.listdir(path)
#globalfile.write(';'.join(files))
#globalfile.write('\n')

file_rows = [files] # adjusted so that its a list in list

#get all values
for filename in glob.glob(os.path.join(path, '*.csv')):
    tmp_rows = []
    with open(filename, 'r') as csvfile:
        textcsv = csv.reader(csvfile, delimiter=';')
        for row in textcsv:
            tmp_rows += [row] # adjusted for list in lists
    file_rows += tmp_rows
with open('transposed.csv') as f:
    gf = csv.writer(f)
    gf.writerows(zip(*file_rows))

如果每个原始文件没有严格限定1行,您将获得有趣的结果。

更新: 我做了一个小例子,确实有效。

files = list('abcd')
file_rows = [files]
for filename in [range(i, i+4) for i in range(0, 12, 4)]:
    tmp_rows = []
    fake_csv = [list(filename)]
    for row in fake_csv:
        tmp_rows += [row] # change to [row, row] to see what happens
                          # in case of multiple rows in original csv
    file_rows += tmp_rows
transposed = list(zip(*file_rows))
print(transposed)

在完成测试代码后,我调整了原始代码,使其在列表中列出,这是唯一的。因此,如果您在更改后仍然得到有趣的结果,那么现在是因为您没有统一的输入数据,在这种情况下您需要决定如何处理。例如,zip将默默地仅输出所有原始行的最短列表的长度。要解决此问题,您需要以编码方式添加,以便所有列表与最长行具有相同的长度。