2

結合したい2000個のファイルのリストがあります:

01-0628-11A-01D-0356-01_hg19
01-0628-11A-01D-0356-01_hg20
01-0628-11A-01D-0356-01_hg21
01-1372-11A-01D-0356-01_hg16
01-1372-11A-01D-0356-01_hg17
...


既にファイルをグロブに取得し、正規表現を使用してファイルの名前を共通の識別子 (以下に示す 6 桁のコード) に変更しましたが、識別子ごとにさまざまな数の元のファイルがあります。

01-0628
01-0628
01-0628
01-1372
01-1372
...

私はもともとリーダーを使用して、一般的な名前の各ファイルを開くつもりでしたが、これを行うためのより効率的な方法があるかどうか疑問に思っていました.

私が望む最終的な出力は次のとおりです。共通の識別子を持つ各ファイルが1つにまとめられています。

01-0628
01-1372
...

すべてのファイルには同様の形式のデータが含まれているため、既存のファイルを新しいファイルに追加するだけで問題はありません。

4

1 に答える 1

1

これらのcsvに類似または同一のフィールドがあると仮定します。このコードは機能するはずです。csv 行を Python 辞書に変換する csv モジュールの DictReader および DictWriter クラスを使用します。

1) グロブ化された csv ファイルを in_csv_dir から (ファイル名、行) ディクショナリに開き、読み込みます。

2) ファイル名と prefix_length 変数に基づいて、csv 行を (接頭辞、行) 辞書にグループ化します。

3) 各プレフィックス グループのフィールドを結合し、結合された csv を out_csv_dir に作成します。

4) 辞書キーは順不同であるため、csv には特定のフィールド順がある場合があります。これは field_order に入力できます。これは csv フィールドをソートしますが、field_order で定義されていないフィールドでは失敗しません。

import os
import sys

# Import System libraries
from csv import DictReader, DictWriter
import glob

in_csv_dir = ".\\csvs"
out_csv_dir = ".\\combined_csvs"
prefix_length = 2

field_order = ["NAME", "TITLE", "COMPANY", "LOCATION"]
field_check = lambda q: field_order.index(q) if(field_order.count(q)) else sys.maxint
csvs = {}
gotten_files = glob.glob(os.path.join(in_csv_dir, "*.csv"))
for glob_filename in gotten_files:
    print "%-11s%s" % ("Opening:", glob_filename)
    file_obj = open(glob_filename, "rb")
    cur_reader = DictReader(file_obj)
    cur_record = [q for q in cur_reader.__iter__()]
    file_obj.close()
    if(cur_record):
        (path, filename_ext) = os.path.split(glob_filename)
        (filename, ext) = os.path.splitext(filename_ext)
        csvs[filename] = cur_record

csv_prefixes = list(set([x[:prefix_length] for x in csvs.keys()]))
csv_groups = dict([(prefix, []) for prefix in csv_prefixes])
map(lambda (key, value): csv_groups[key[:prefix_length]].extend(value), csvs.items())

for (key, sub_csvs) in csv_groups.items():
    com_keys = list(reduce(lambda x, y: x|set(y.keys()), sub_csvs, set([])))
    com_keys.sort(cmp=lambda x, y: field_check(x) - field_check(y))

    filename = os.path.join(out_csv_dir, "%s.csv" % key)
    print "%-11s%s" % ("Combining:", filename)
    file_obj = open(filename, "wb")
    temp_csv = DictWriter(file_obj, com_keys)

    temp_csv.writerow(dict(zip(com_keys, com_keys)))
    map(lambda x: temp_csv.writerow(x), sub_csvs)
    file_obj.close()
于 2013-07-03T12:26:59.267 に答える