2012-06-25 2 views
0

여러 CSV 파일을 파이썬과 비교하고 보고서를 출력하려고합니다. 비교할 CSV 파일의 수는 다양하므로 디렉토리에서 목록을 가져 오도록하고 있습니다. 각 CSV에는 2 개의 열이 있습니다. 첫 번째는 지역 번호 및 교환이며, 두 번째는 가격입니다. 예 :여러 CSV 파일을 파이썬과 비교하십시오.

1201007,0.006 
1201032,0.0119 
1201040,0.0106 
1201200,0.0052 
1201201,0.0345 

파일이 모두 같은 지역 코드와 교류, 그래서보다는 라인 비교하여 라인을 포함하지 않습니다, 나는 키로서 첫 번째 필드를 사용해야합니다. 그런 다음 file1이 file2에 200 개의 불일치를, file2보다 371 개의 낮은 가격을, file2보다 562 개의 높은 가격을 갖는 보고서를 생성해야합니다. 나는 각 파일을 서로 비교하기 위해 이것을 생성해야하므로이 단계는 file3, file4 ....에 대해 반복되고 files2는 files3 등에 대해 반복 될 것입니다. 나는 자신을 Python에 대한 상대적 멍청함이라고 생각할 것입니다. 아래는 제가 지금까지 가지고있는 코드입니다. 디렉토리에있는 파일을 잡고 전체 파일에서 모든 파일의 가격을 인쇄합니다.

import csv 
import os 

count = 0 
#dir containing CSV files 
csvdir="tariff_compare" 
dirList=os.listdir(csvdir) 
#index all files for later use 
for idx, fname in enumerate(dirList): 
    print fname 
    dic_read = csv.reader(open(fname)) 
    for row in dic_read: 
     key = row[0] 
     price = row[1] 
     print price 
     count += 1 
print count 

답변

0

이렇게하면 모든 데이터가 메모리에 저장 될 수 있다고 가정합니다. 그렇지 않은 경우 한 번에 일부 파일 세트 만로드하거나 한 번에 두 개 파일 만로드해야합니다.

비교를 수행하여 출력을 summary.csv 파일 (파일 쌍당 하나의 행)에 씁니다.

import csv 
import glob 
import os 
import itertools 

def get_data(fname): 
    """ 
    Load a .csv file 
    Returns a dict of {'exchange':float(price)} 
    """ 
    with open(fname, 'rb') as inf: 
     items = (row.split() for row in csv.reader(inf)) 
     return {item[0]:float(item[1]) for item in items} 

def do_compare(a_name, a_data, b_name, b_data): 
    """ 
    Compare two data files of {'key': float(value)} 

    Returns a list of 
     - the name of the first file 
     - the name of the second file 
     - the number of keys in A which are not in B 
     - the number of keys in B which are not in A 
     - the number of values in A less than the corresponding value in B 
     - the number of values in A equal to the corresponding value in B 
     - the number of values in A greater than the corresponding value in B 
    """ 
    a_keys = set(a_data.iterkeys()) 
    b_keys = set(b_data.iterkeys()) 

    unique_to_a = len(a_keys - b_keys) 
    unique_to_b = len(b_keys - a_keys) 

    lt,eq,gt = 0,0,0 
    pairs = ((a_data[key], b_data[key]) for key in a_keys & b_keys) 
    for ai,bi in pairs: 
     if ai < bi: 
      lt +=1 
     elif ai == bi: 
      eq += 1 
     else: 
      gt += 1 

    return [a_name, b_name, unique_to_a, unique_to_b, lt, eq, gt] 

def main(): 
    os.chdir('d:/tariff_compare') 

    # load data from csv files 
    data = {} 
    for fname in glob.glob("*.csv"): 
     data[fname] = get_data(fname) 

    # do comparison 
    files = data.keys() 
    files.sort() 
    with open('summary.csv', 'wb') as outf: 
     outcsv = csv.writer(outf) 
     outcsv.writerow(["File A", "File B", "Unique to A", "Unique to B", "A<B", "A==B", "A>B"]) 
     for a,b in itertools.combinations(files, 2): 
      outcsv.writerow(do_compare(a, data[a], b, data[b])) 

if __name__=="__main__": 
    main() 

편집 : user1277476 좋은 지적한다; 교환을 통해 파일을 미리 정렬하거나 정렬 된 순서로 이미 정렬 한 경우 메모리에있는 각 행에 대한 현재 행만 유지하면서 모든 파일을 동시에 반복 할 수 있습니다.

이 각 교환 항목에 대한보다 심층적 인 비교를 할 수 있도록 것 - 등의 값, 또는 상단 또는 하단 N 값,

+0

곧 구현할 예정이지만 정확하게 필요한 것 같습니다. 고맙습니다! – user1480902

0

가 포함 된 파일의 수를 파일이 작은 경우에, 당신은 뭔가를 할 수 당신이 당신의 데이터를 사전에 키와 결과 값을 비교하는이

data = dict() 
for fname in os.listdir(csvDir): 
    with open(fname, 'rb') as fin: 
     data[fname] = dict((key, value) for key, value in fin.readlines()) 
# All the data is now loaded into your data dictionary 
# data -> {'file1.csv': {1201007: 0.006, 1201032: 0.0119, 1201040: 0.0106}, 'file2.csv': ...} 

같은 기본적인 이제 모든 것을 쉽게 액세스 할 수 있습니다.

그렇지 않으면 메모리에로드 할 수없는 더 큰 데이터 세트가있는 경우 한 번에 2 개의 파일로 작업하고 메모리에 하나만 저장하는 것이 좋습니다. itertools.combinations이라는 파일명 조합 목록을 만들 수 있습니다.이 파일은 combinations(filenames, 2)처럼 사용할 수있는 고유 한 조합으로 2 개의 파일 이름 쌍을 생성합니다.

거기에서 당신은 여전히 ​​더 나아질 수 있습니다. 그러나 그것은 당신을 가야합니다.

0

파일을 비교하기 전에 파일을 정렬하는 것이 좋습니다. 그런 다음 mergesort의 병합 단계와 유사한 알고리즘을 사용하여 비교를 수행하십시오.

중복 레코드로 무엇을 할 것인가에 대해 생각할 필요가 있습니다. 예를 들어, file1에 1234567,0.1이 두 번 있고 file2에도 2가 있습니까? file1에 3 개가 있고 file2에 5 개가있는 경우와 그 반대의 경우는 어떻게됩니까?

http://en.literateprograms.org/Merge_sort_%28Python%29 
http://stromberg.dnsalias.org/~strombrg/sort-comparison/ 
http://en.wikipedia.org/wiki/Merge_sort 
+0

그들은 이미 선행되었습니다. 중복에 관해서는, 그것이 하나의 파일에있는 데이터의 유형 때문에 절대적으로 중복되지 않습니다. – user1480902

관련 문제