簡體   English   中英

比較4個CSV文件之間的數據並將它們寫入單獨的輸出文件

[英]Comparing data between 4 csv files and writing them to separate output files

有人可以建議我如何改善我的代碼嗎? 我有4個大型csv文件。 第一個是參考文件,其他三個文件(文件1,文件2和文件3)與之比較。 在文件中,有三列。 每行是一個單位(例如ABC,DEF,GHI是3個獨立的單位)。

col_1   col_2    col_3 
 A        B         C    
 D        E         F
 G        H         I

我想將file1,file2和file3與參考文件進行比較。 如果參考文件中每行的單位均存在於所有3個文件中,則我想將它們寫入文件A。如果3行文件中的至少1個中存在每行單位,則應將其寫入文件B。如果這3個文件中的每行都不存在單位,我想將它們寫入文件C。我當前的策略是將文件作為4個單獨的列表附加並進行比較。 我意識到這種方法需要占用大量內存。 另外,我的腳本已經運行了很長時間,沒有最終輸出。 因此,我想知道是否有更有效的方法來解決這個問題?

下面是我的代碼:

import csv

reference_1 = open ('reference.csv', 'rt', newline = '')
reader = csv.reader(reference_1, delimiter = ',')
file1 = open ('file1.csv','rt', newline = '')
reader1 = csv.reader(file1, delimiter = ',')
file2 = open ('file2.csv', 'rt',newline = '')
reader2 = csv.reader(file2, delimiter = ',')                 
file3 = open ('file3.csv', 'rt',newline = '')
reader3 = csv.reader(file3, delimiter = ',')                 


Common = open ('Common.csv', 'w',newline = '')
writer1 = csv.writer(Common, delimiter = ',')                 
Partial = open ('Partial.csv', 'w',newline = '')
writer2 = csv.writer(Partial, delimiter = ',')                   
Absent = open ('Absent.csv', 'w',newline = '')
writer3 = csv.writer(Absent, delimiter = ',')

reference = []
fileA = []
fileB = []
fileC = []

for row in reader:
                 reference.append (row)

for row in reader1:
                 fileA.append(row)

for row in reader2:
                 fileB.append(row)

for row in reader3:
                 fileC.append(row)


for row in reference:
    if row in fileA and row in fileB  and row in fileC:
        writer1.writerow (row)
        continue
    elif row in fileA or row in fileB or row in fileC:
        writer2.writerow (row)
        continue
    else:
        writer3.writerow (row)


reference_1.close() 
file1.close()
file2.close()
file3.close()
Common.close()
Partial.close()
Absent.close()

假設行的順序並不重要,並且參考文件中沒有重復的行,這是一個使用set的選項。

def file_to_set(filename):
    """Opens a file and returns a set containing each line of the file."""
    with open(filename) as f:
        return set(f.read().splitlines(True))

def set_to_file(s, filename):
    """Writes a set to file."""
    with open(filename, 'w') as f:
        f.writelines(s)

def compare_files(ref_filename, *files):
    """Compares a reference file to two or more files."""
    if len(files) < 2:
        raise TypeError("compare_files expected at least 2 files, got %s" %
                        len(files))

    ref = file_to_set(ref_filename)
    file_data = [file_to_set(f) for f in files]

    all = file_data[0].union(*file_data[1:])
    common = ref.intersection(*file_data)
    partial = ref.intersection(all).difference(common)
    absent = ref.difference(all)

    set_to_file(common, 'common.csv')
    set_to_file(partial, 'partial.csv')
    set_to_file(absent, 'absent.csv')

compare_files('reference.csv', 'file1.csv', 'file2.csv', 'file3.csv')

這個想法是:

  1. 創建包含文件每一行的集合。
  2. 制作一個包含所有文件(參考文件除外)中每一行的集合( all )。
  3. 使一個集合( common )僅包含每個文件(包括參考文件)中的行。
  4. 制作一組( partial ),其中包含參考文件中的行,這些行也出現在至少一個但不是所有其他文件中。
  5. 進行一個設置( absent ),其中包含僅存在於參考文件中的行。
  6. 向文件寫入commonpartialabsent

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM