使用 Python 比较两个大型数据集



我正在逐行比较 2 个文件

JSON中的一个喜欢这个:

{firstname: "xxx", lastname: "xxx"}
{firstname: "yyy", lastname: "yyy"}

csv 中的一个喜欢这个:

firstname;lastname;
xxx;xxx
yyy;yyy

两个列表都按名字排序,我创建了 2 个嵌套循环来存储索引和匹配计数,如下所示:

i = j = 0
chunks = []
while i < len(list_json):
matched = 0
while j < len(list_csv):
if list_json[i]['firstname'][0] < list_csv[j][0][0]:
j = 0
break
if ist_json[i]['firstname'] == list_csv[j][0]:
matched += 1
# more thing here 
j += 1
chunck.append((i,matched)

我的问题是两个文件都在大约 1 M 行,而且需要太长(超过 24 小时(。 你有什么想法可以快速解决这个问题吗?

a = [{'firstname': "aaa", 'lastname': "bbb"},
{'firstname': "xxx", 'lastname': "xxx"},
{'firstname': "xxx", 'lastname': "yyy"},
{'firstname': "yyy", 'lastname': "xxx"},
{'firstname': "yyy", 'lastname': "yyy"},
]
b = [['xxx','xxx'],
['xxx','xxx'],
['yyy','yyy'],
['zzz','zzz']]
list_json = a
list_csv = b

您的一些逻辑错误,并且在错误的时间更改了索引。 我认为这可以解决您的解决方案。您的解决方案仅计算名字匹配项 - 我添加了名字和姓氏匹配的测试。

i = j = 0
chunks = []
f_and_l_chunks = []
while i < len(list_json):
matched = 0
f_and_l_matched = 0
fjson,ljson = list_json[i]['firstname'],list_json[i]['lastname']
while j < len(list_csv):
fcsv,lcsv = list_csv[j][0],list_csv[j][1]
#print(f'i:{i} j:{j} | {fjson},{fcsv}')
if fjson[0] < fcsv[0]:  # sorted by first name so short circuit 
break
if fjson == fcsv:    # compare first only like your example
#print('          matched')
matched += 1
if (fjson,ljson) == (fcsv,lcsv):    # compare first and last
f_and_l_matched += 1
j += 1
chunks.append((i,matched))
f_and_l_chunks.append((i,f_and_l_matched))
i += 1
j = 0

我很确定两个字符串之间的小于比较与比较第一个字符一样快。

if fjson[0] < fcsv[0]:  # sorted by first name so short circuit 
break

效率与

if fjson < fcsv:  # sorted by first name so short circuit 
break

看来我误解或没有彻底阅读你的问题。这是我的第一个答案,无关紧要,但我会留给后人。

从每个容器中获取名字,并使用 set 交集查找常见项。

import operator
afn = map(operator.itemgetter('firstname'),a)
bfn = map(operator.itemgetter(0),b)
common = set(afn).intersection(bfn)
>>> common
{'xxx', 'yyy'}

或者匹配名字和姓氏使用相同的过程。

from operator import itemgetter
anames = map(itemgetter('firstname','lastname'), a)
bnames = map(itemgetter(0,1),b)
common = set(anames).intersection(bnames)

最新更新