web-dev-qa-db-ja.com

700万行のCSVを特定の列で分割する

非常に大きな(700万行)CSVファイルを特定の数値列でいくつかの異なるシート/ファイルに分割するにはどうすればよいですか。約10個の異なるファイルに分割する必要があります。

2
BrandonMXB

これを使用してください Python プログラム:

#!/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として保存し、エクスプローラーまたはコマンドラインから実行します。

たとえば、列1に基づいてsuperuser.csvを分割し、出力ファイルをdstdirの下に書き込むには次を使用します。

python split-csv.py superuser.csv 1 dstdir

引数なしで実行すると、TkinterベースのGUIにより、入力ファイル、列(1ベースのインデックス)、および宛先ディレクトリを選択するように求められます。

4

これは、awkを使用したこのワンライナーと同じくらい簡単です。

awk -F ',' '{ print > ("split-" $1 ".csv") }' 7mil.csv
  • ここでの入力ファイルは7mil.csvです。
  • 決定列番号はドル記号で示されます。 3番目の列の場合、$3ではなく$1になります。
  • 列の値は、結果のファイル名を生成するために使用されます。したがって、たとえば、値が42のすべての行は、split-42.csvという名前のファイルに含まれます。
  • フィールド区切り文字はコンマです
    • これは、値が数値であり、削除する必要のある引用符がないために機能します
    • ただし、ファイル内の文字列にコンマが含まれていないことも必要です(少なくとも数値列の前では)

したがって、これはすべての行を読み取り、値に対応するファイルに出力するだけです。ファイルに追加されるため、2回実行すると、すべてのデータが複製されることに注意してください。したがって、開始するその命名パターンのファイルがないことを確認してください:del split-*.cvs

これを試すのが難しいのは、Windowsにawkをインストールすることです。 gawk for Windowsここで実行するためのいくつかのヒント があります。

5
Ken

区切り それができます。非常に高速な大きなcsvファイル(「最大20億行と200万列のサイズ!」)を開きます。垂直分割を使用するか、列を選択します。

それを行うことができるかもしれない別のソフトウェアは Emeditor です。

1
Erb