按特定列拆分 700 万行 CSV

按特定列拆分 700 万行 CSV

我该如何根据特定数字列将一个非常大的(700 万行)CSV 文件拆分为几个不同的工作表/文件。它应该拆分成大约 10 个不同的文件。

答案1

用这个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 的 GUI 将提示您选择输入文件、列(基于 1 的索引)和目标目录。

答案2

这可能就像下面这样简单awk

awk -F ',' '{ print > ("split-" $1 ".csv") }' 7mil.csv
  • 此处的输入文件是7mil.csv
  • 决定性列号用美元符号表示。如果是第三列,则应该$3改为$1
  • 列值用于生成结果文件名。例如,每行包含该值的内容42都将位于名为split-42.csv
  • 字段分隔符是逗号
    • 这样做的原因是/如果值是数字,并且没有任何需要删除的引号
    • 但还要求文件中的任何字符串中都没有逗号(至少在数字列之前没有)

因此,这只是读取每一行并将其打印到与该值相对应的文件中。请注意,它会添加到文件中,因此如果您运行两次,所有数据都会重复;因此请确保没有具有该命名模式的文件:del split-*.cvs

尝试这个的困难部分是awk在 Windows 上安装。Windows 版 gawk和一个这里有一些运行它的技巧

答案3

划界可以做到这一点。它可以非常快速地打开大型 csv 文件(“最多 20 亿行和 200 万列!”)。使用垂直分割和/或选择您的列。

另一个可以做到这一点的软件是埃米迪托

相关内容