2

Как бы я разбил очень большой (7 миллионов строк) CSV-файл на несколько разных листов / файлов по определенному числовому столбцу. Он должен быть разбит на 10 разных файлов.

3 ответа3

4

Это может быть так же просто, как этот однострочный с awk:

awk -F ',' '{ print > ("split-" $1 ".csv") }' 7mil.csv
  • Входной файл здесь 7mil.csv
  • Номер решающей колонки обозначается знаком доллара. Если бы это был третий столбец, это было бы $3 вместо $1
  • Значение столбца используется для генерации результирующего имени файла. Так, например, каждая строка со значением 42 будет в файле с именем split-42.csv
  • Разделитель полей - это запятая
    • который работает, потому что / если значение является числовым, и не имеет кавычек, которые должны быть удалены
    • но также требует, чтобы в строках файла не было запятых (по крайней мере, перед числовым столбцом)

Так что это просто читает каждую строку и печатает ее в файл, который соответствует значению. Обратите внимание, что он добавляет в файл, поэтому, если вы запустите его дважды, все данные будут дублированы; поэтому убедитесь, что нет файлов с этим шаблоном имен для запуска: del split-*.cvs

Сложнее всего попробовать установить awk на Windows. Здесь есть gawk для Windows и несколько советов по ее запуску.

3

Используйте эту программу на 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) и каталог назначения.

1

Делимит может это сделать. Он очень быстро открывает большие CSV-файлы («до 2 миллиардов строк и 2 миллионов столбцов большого размера!»).«). Используйте разделение по вертикали и / или выберите столбцы.

Еще одно программное обеспечение, которое может это сделать, - Emeditor.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .