5

Python での重複の削除について質問があります。たくさんの投稿を読みましたが、まだ解決できていません。次の csv ファイルがあります。

編集

入力:

ID, Source, 1.A, 1.B, 1.C, 1.D
1, ESPN, 5,7,,,M
1, NY Times,,10,12,W
1, ESPN, 10,,Q,,M

出力は次のようになります。

ID, Source, 1.A, 1.B, 1.C, 1.D, duplicate_flag
1, ESPN, 5,7,,,M, duplicate
1, NY Times,,10,12,W, duplicate
1, ESPN, 10,,Q,,M, duplicate 
1, NY Times, 5 (or 10 doesn't matter which one),7, 10, 12, W, not_duplicate

つまり、ID が同じ場合、ソース「NY Times」の行から値を取得し、「NY Times」の行に空白の値があり、「ESPN」ソースの重複行にそのセルの値がある場合、「ESPN」ソースの行から値を取得します。出力するには、元の 2 行に重複としてフラグを立て、3 行目を作成します。

もう少し明確にするために、このスクリプトをさまざまな列ヘッダーを持つさまざまな csv ファイルで実行する必要があるため、次のようなことはできません。

    def main():
        with open(input_csv, "rb") as infile:
            input_fields = ("ID", "Source", "1.A", "1.B", "1.C", "1.D")
            reader = csv.DictReader(infile, fieldnames = input_fields)
            with open(output_csv, "wb") as outfile:
                output_fields = ("ID", "Source", "1.A", "1.B", "1.C", "1.D", "d_flag")
                writer = csv.DictWriter(outfile, fieldnames = output_fields)
                writer.writerow(dict((h,h) for h in output_fields))
                next(reader)
                first_row = next(reader)
                for next_row in reader:
                    #stuff

テーブル内の他の列とは関係なく、プログラムを最初の 2 つの列で実行したいからです。つまり、「ID」と「ソース」はすべての入力ファイルに含まれますが、残りの列はファイルによって異なります。

あなたが提供できるどんな助けでも大歓迎です!参考までに、「ソース」は NY タイムズ、ESPN、またはウォール ストリート ジャーナルのみであり、重複の優先順位は次のとおりです: 利用可能な場合は NY タイムズ、そうでない場合は ESPN、それ以外の場合はウォール ストリート ジャーナル。これは、すべての入力ファイルに当てはまります。

4

1 に答える 1

2

以下のコードは、すべてのレコードを大きなディクショナリに読み込みます。そのキーはその識別子であり、値はソース名をデータ行全体にマッピングするディクショナリです。次に、辞書を反復処理して、要求した出力を提供します。

import csv

header = None
idfld = None
sourcefld = None

record_table = {}

with open('input.csv', 'rb') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        row = [x.strip() for x in row]

        if header is None:
            header = row
            for i, fld in enumerate(header):
                if fld == 'ID':
                    idfld = i
                elif fld == 'Source':
                    sourcefld = i
            continue

        key = row[idfld]
        sourcename = row[sourcefld]

        if key not in record_table:
            record_table[key] = {sourcename: row, "all_rows": [row]}
        else:
            if sourcename in record_table[key]:
                cur_row = record_table[key][sourcename]
                for i, fld in enumerate(row):
                    if cur_row[i] == '':
                        record_table[key][sourcename][i] = fld
            else:
                record_table[key][sourcename] = row
            record_table[key]["all_rows"].append(row)

print ', '.join(header) + ', duplicate_flag'

for recordid in record_table:
    rowdict = record_table[recordid]

    final_row = [''] * len(header)

    rowcount = len(rowdict)

    for sourcetype in ['NY Times', 'ESPN', 'Wall Street Journal']:
        if sourcetype in rowdict:
            row = rowdict[sourcetype]
            for i, fld in enumerate(row):
                if final_row[i] != '':
                    continue
                if fld != '':
                    final_row[i] = fld

    if rowcount > 1:
        for row in rowdict["all_rows"]:
            print ', '.join(row) + ', duplicate'

    print ', '.join(final_row) + ', not_duplicate'
于 2013-01-10T20:17:57.313 に答える