これは、すべてのデータがメモリに収まることを前提としています。そうでない場合は、一度にいくつかのファイル セットだけをロードするか、一度に 2 つのファイルだけをロードする必要があります。
比較を行い、出力を summary.csv ファイルに書き込みます (ファイルのペアごとに 1 行)。
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 値など。