Python: CSV запись по столбцу, а не по строке - PullRequest
36 голосов
/ 11 ноября 2010

У меня есть скрипт на 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 не закончится. Кто-нибудь может мне помочь?


EDIT

Цикл while может длиться более 100 000 циклов

Ответы [ 7 ]

36 голосов
/ 11 ноября 2010

Причина 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)]
6 голосов
/ 20 декабря 2016
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])
5 голосов
/ 11 ноября 2010

Обновление строк в файле не поддерживается в большинстве файловых систем (строка в файле - это просто данные, заканчивающиеся символом новой строки, следующая строка начинается сразу после этого).

На мой взгляд, у вас есть два варианта:

  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 генерирует бесконечную последовательность чисел

1 голос
/ 27 октября 2016

Прочитайте его по строкам, а затем перенесите в командную строку. Если вы используете Unix, установите csvtool и следуйте инструкциям в: https://unix.stackexchange.com/a/314482/186237

1 голос
/ 11 ноября 2010

Предположим, что (1) у вас нет большой памяти (2) у вас есть заголовки строк в списке (3) все значения данных являются числами с плавающей запятой; если все они целые числа до 32- или 64-битных, это даже лучше.

В 32-битном Python для сохранения числа с плавающей точкой в ​​списке требуется 16 байтов для объекта с плавающей точкой и 4 байта для указателя в списке; всего 20. Хранение числа с плавающей точкой в ​​массиве array.array ('d') занимает всего 8 байтов. Все более впечатляющая экономия возможна, если все ваши данные имеют целочисленные значения (отрицательные значения?), Которые умещаются в 8, 4, 2 или 1 байт (-ов) - особенно на недавнем Python, где все целые числа являются длинными.

Следующий псевдокод предполагает, что значения с плавающей точкой хранятся в файле array.array ('d'). Если у вас действительно нет проблем с памятью, вы все равно можете использовать этот метод; Я добавил комментарии, чтобы указать необходимые изменения, если вы хотите использовать список.

# 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)
1 голос
/ 11 ноября 2010

как насчет 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
0 голосов
/ 11 ноября 2010

В качестве альтернативного подхода к потоковой передаче:

  • выгрузите каждый столбец в файл
  • используйте команду вставки python или unix, чтобы присоединиться к tab, csv, как угодно.*

    Оба шага должны отлично справляться с паром.

    Подводные камни:

    • если у вас есть тысячи столбцов, вы можете столкнуться с лимитом дескриптора файла unix!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...