Есть ли способ добавить строку заголовка в CSV без загрузки CSV в память в python? У меня есть CSV на 18 ГБ, я хочу добавить заголовок, и все методы, которые я видел, требуют загрузки CSV в память, что явно неосуществимо.Добавить заголовок в CSV без загрузки CSV
ответ
Просто используйте тот факт, что csv
модуля итерации по строкам, так что никогда не загружает файл целиком в памяти
import csv
with open("huge_csv.csv") as fr, open("huge_output.csv","w",newline='') as fw:
cr = csv.reader(fr)
cw = csv.writer(fw)
cw.writerow(["title1","title2","title3"])
cw.writerows(cr)
с использованием writerows
обеспечивает очень хорошую скорость. Здесь хранится память. Все делается по очереди. Поскольку данные правильно обработаны, вы даже можете изменить разделитель и/или цитату в выходном файле.
Вам нужно будет переписать весь файл. Простейшие не использовать Python
echo 'col1, col2, col2,... ' > out.csv
cat in.csv >> out.csv
решения Python на основе будет работать на гораздо более высокий уровень и будет намного медленнее. 18GB - это много данных. Лучше работать с функциональностью операционной системы, которая будет самой быстрой.
И если вы не хотите покидать Python, вы всегда можете обернуть его в вызов 'subprocess.call()'. Или даже писать первую строку в Python, как в ответе @ maximilian-peters. –
Это на самом деле самое быстрое решение, см. Тест в другом ответе. –
спасибо @MaximilianPeters за то, что нашли время, чтобы провести сравнение – e4c5
Проведено сравнение трех предлагаемых решений для файла CSV размером 200 МБ с 10^6 строками и 10 столбцами (n = 50). Соотношение примерно одинаковое для больших и меньших файлов (от 10 МБ до 8 ГБ).
ф: shutil: csv_reader 1:10:55
т.е. с помощью встроенного cp
функции примерно в 55 раз быстрее, чем при использовании csv
модуля Питона.
Компьютер:
- регулярные HDD
- Python 3.5.2 64-битный
- Ubuntu 16,04
- i7-3770
import csv
import random
import shutil
import time
import subprocess
rows = 1 * 10**3
cols = 10
repeats = 50
shell_script = '/tmp/csv.sh'
input_csv = '/tmp/temp.csv'
output_csv = '/tmp/huge_output.csv'
col_titles = ['titles_' + str(i) for i in range(cols)]
with open(shell_script, 'w') as f:
f.write("#!/bin/bash\necho '{0}' > {1}\ncat {2} >> {1}".format(','.join(col_titles), output_csv, input_csv))
with open(shell_script, 'w') as f:
f.write("echo '{0}' > {1}\ncat {2} >> {1}".format(','.join(col_titles), output_csv, input_csv))
subprocess.call(['chmod', '+x', shell_script])
run_times = dict([
('csv_writer', list()),
('external', list()),
('shutil', list())
])
def random_csv():
with open(input_csv, 'w') as csvfile:
csv_writer = csv.writer(csvfile, delimiter=',')
for i in range(rows):
csv_writer.writerow([str(random.random()) for i in range(cols)])
with open(output_csv, 'w'):
pass
for r in range(repeats):
random_csv()
#http://stackoverflow.com/a/41982368/2776376
start_time = time.time()
with open(input_csv) as fr, open(output_csv, "w", newline='') as fw:
cr = csv.reader(fr)
cw = csv.writer(fw)
cw.writerow(col_titles)
cw.writerows(cr)
run_times['csv_writer'].append(time.time() - start_time)
random_csv()
#http://stackoverflow.com/a/41982383/2776376
start_time = time.time()
subprocess.call(['bash', shell_script])
run_times['external'].append(time.time() - start_time)
random_csv()
#http://stackoverflow.com/a/41982383/2776376
start_time = time.time()
with open('header.txt', 'w') as header_file:
header_file.write(','.join(col_titles))
with open(output_csv, 'w') as new_file:
with open('header.txt', 'r') as header_file, open(input_csv, 'r') as main_file:
shutil.copyfileobj(header_file, new_file)
shutil.copyfileobj(main_file, new_file)
run_times['shutil'].append(time.time() - start_time)
print('#'*20)
for key in run_times:
print('{0}: {1:.2f} seconds'.format(key, run_times[key][-1]))
print('#'*20)
print('Averages')
for key in run_times:
print('{0}: {1:.2f} seconds'.format(key, sum(run_times[key])/len(run_times[key])))
Если вы действительно хотите сделать это в Python, вы можете создать файл заголовка первой, а затем объединить его с 2-го файла с помощью shutil.copyfileobj
.
import shutil
with open('header.txt', 'w') as header_file:
header_file.write('col1;col2;col3')
with open('new_file.csv', 'w') as new_file:
with open('header.txt', 'r') as header_file, open('main.csv', 'r') as main_file:
shutil.copyfileobj(header_file, new_file)
shutil.copyfileobj(main_file, new_file)
- 1. Добавить заголовок для CSV-файла?
- 2. exporthell export csv добавить заголовок?
- 3. Добавить заголовок в объект или строку csv
- 4. Powershell добавить заголовок в пустую csv
- 5. Добавить заголовок в несколько файлов CSV
- 6. Python добавить заголовок в файл csv
- 7. Powershell добавить заголовок/строку в CSV
- 8. import-csv, добавить столбец1, установить заголовок, заполнить, export-csv
- 9. загрузки CSV в JavaScript
- 10. Замена/редактировать заголовок Csv
- 11. чтение удаленного файла csv без загрузки
- 12. Как проверить заголовок CSV файл
- 13. Повторяющийся заголовок в CSV файл
- 14. Обновить заголовок CSV Использование CsvReader
- 15. Джанго заголовок CSV и проблема
- 16. Проверьте, существует ли CSV-заголовок
- 17. добавить несколько файлов .csv
- 18. Rails CSV Ошибки загрузки
- 19. Ошибка загрузки файла CSV
- 20. Ошибка загрузки php csv
- 21. Ошибка загрузки CSV-файла
- 22. загрузки файла CSV
- 23. Php загрузки CSV проблема
- 24. Ошибка загрузки файла csv
- 25. CSV для загрузки
- 26. время загрузки от csv
- 27. Как добавить общий заголовок в файл csv в bash
- 28. Как добавить заголовок в файл csv в Python?
- 29. Добавить строку заголовка в .csv
- 30. загрузки CSV разбора в Rails
Вы пробовали использовать метод writeheader для DictWriter? (https://docs.python.org/3/library/csv.html) Я не знаю точного ответа, просто идея: если вы откроете файл с помощью «a» и попытаетесь использовать writeheader, это работает? Было бы хорошо, если бы вы попытались с копией исходного файла, если что-то не так. – Kroy
См. Обновленный ответ для сравнения скорости трех методов. –