Как бы я разбил очень большой (7 миллионов строк) CSV-файл на несколько разных листов / файлов по определенному числовому столбцу. Он должен быть разбит на 10 разных файлов.
3 ответа
Это может быть так же просто, как этот однострочный с awk
:
awk -F ',' '{ print > ("split-" $1 ".csv") }' 7mil.csv
- Входной файл здесь
7mil.csv
- Номер решающей колонки обозначается знаком доллара. Если бы это был третий столбец, это было бы
$3
вместо$1
- Значение столбца используется для генерации результирующего имени файла. Так, например, каждая строка со значением
42
будет в файле с именемsplit-42.csv
- Разделитель полей - это запятая
- который работает, потому что / если значение является числовым, и не имеет кавычек, которые должны быть удалены
- но также требует, чтобы в строках файла не было запятых (по крайней мере, перед числовым столбцом)
Так что это просто читает каждую строку и печатает ее в файл, который соответствует значению. Обратите внимание, что он добавляет в файл, поэтому, если вы запустите его дважды, все данные будут дублированы; поэтому убедитесь, что нет файлов с этим шаблоном имен для запуска: del split-*.cvs
Сложнее всего попробовать установить awk
на Windows. Здесь есть gawk для Windows и несколько советов по ее запуску.
Используйте эту программу на Python 3 :
#!/usr/bin/env python3
import binascii
import csv
import os.path
import sys
from tkinter.filedialog import askopenfilename, askdirectory
from tkinter.simpledialog import askinteger
def split_csv_file(f, dst_dir, keyfunc):
csv_reader = csv.reader(f)
csv_writers = {}
for row in csv_reader:
k = keyfunc(row)
if k not in csv_writers:
csv_writers[k] = csv.writer(open(os.path.join(dst_dir, k),
mode='w', newline=''))
csv_writers[k].writerow(row)
def get_args_from_cli():
input_filename = sys.argv[1]
column = int(sys.argv[2])
dst_dir = sys.argv[3]
return (input_filename, column, dst_dir)
def get_args_from_gui():
input_filename = askopenfilename(
filetypes=(('CSV', '.csv'),),
title='Select CSV Input File')
column = askinteger('Choose Table Column', 'Table column')
dst_dir = askdirectory(title='Select Destination Directory')
return (input_filename, column, dst_dir)
if __name__ == '__main__':
if len(sys.argv) == 1:
input_filename, column, dst_dir = get_args_from_gui()
elif len(sys.argv) == 4:
input_filename, column, dst_dir = get_args_from_cli()
else:
raise Exception("Invalid number of arguments")
with open(input_filename, mode='r', newline='') as f:
split_csv_file(f, dst_dir, lambda r: r[column-1]+'.csv')
# if the column has funky values resulting in invalid filenames
# replace the line from above with:
# split_csv_file(f, dst_dir, lambda r: binascii.b2a_hex(r[column-1].encode('utf-8')).decode('utf-8')+'.csv')
Сохраните его как split-csv.py
и запустите из Проводника или из командной строки.
Например, чтобы разделить superuser.csv
основе столбца 1 и записать выходные файлы с использованием dstdir
:
python split-csv.py superuser.csv 1 dstdir
Если вы запустите его без аргументов, графический интерфейс на основе Tkinter предложит вам выбрать входной файл, столбец (индекс на основе 1) и каталог назначения.