在大文件中查找相同的数字 python
Finding identical numbers in large files python
我在 python 中有两个数据文件,每个文件包含如下两列数据:
3023084 5764
9152549 5812
18461998 5808
45553152 5808
74141469 5753
106932238 5830
112230478 5795
135207137 5800
148813978 5802
154818883 5798
每个文件中大约有 10M 个条目 (~400Mb)。
我必须对每个文件进行排序,并检查一个文件第一列中的任何数字是否与另一个文件第一列中的任何数字匹配。
我目前将文件转换为列表的代码:
ch1 = []
with open('ch1.txt', 'r+') as file:
for line in file:
if ':' not in line:
line = line.split()
ch1.append([line[0], line[1]])
ch2 = []
with open('ch2.txt', 'r+') as file:
for line in file:
if ':' not in line:
line = line.split()
ch2.append([line[0], line[1]])
然后我遍历两个列表以寻找匹配项。找到匹配项后,我会将右侧列的总和添加到新列表 'coin'
coin = []
for item1 in ch1:
for item2 in ch2:
if item1[0] == item2[0]:
coin.append(int(item1[1]) + int(item2[1]))
问题是这需要很长时间或者崩溃。 运行有没有更高效的方法?
有很多 种方法可以改善这一点;例如:
由于只扫描一次ch1.txt
的内容,不需要读入列表,占用内存少,但可能不会加快速度。
如果对每个列表进行排序,则可以更有效地检查匹配项。类似于:
i1, i2 = 0, 0
while i1 < len(ch1) and i2 < len(ch2):
if ch1[i1][0] == ch2[i2][0]:
# Do what you do for matches
...
# Advance both indices
i1 += 1
i2 += 1
elif ch1[i1][0] < ch2[i2][0]:
# Advance index of the smaller value
i1 += 1
else: # ch1[i1][0] > ch2[i2][0]
i2 += 1
如果文件中的数据已经排序,您可以结合两种想法:而不是推进索引,您只需读取相应文件的下一行。这应该会及时提高效率 and space.
一些改进的想法:
- 以这样的方式将数据存储在字典中,第一列是键,第二列是字典的值供以后使用,
- 一个匹配是如果一个键在两个字典的键的交集
代码示例:
# store your data in dicts as following
ch1_dict[line[0]] = line[1]
ch2_dict[line[0]] = line[1]
#this is what you want to achieve
coin = [int(ch1_dict[key]) + int(ch2_dict[key]) for key in ch1_dict.keys() & ch2_dict.keys()]
我在 python 中有两个数据文件,每个文件包含如下两列数据:
3023084 5764
9152549 5812
18461998 5808
45553152 5808
74141469 5753
106932238 5830
112230478 5795
135207137 5800
148813978 5802
154818883 5798
每个文件中大约有 10M 个条目 (~400Mb)。
我必须对每个文件进行排序,并检查一个文件第一列中的任何数字是否与另一个文件第一列中的任何数字匹配。
我目前将文件转换为列表的代码:
ch1 = []
with open('ch1.txt', 'r+') as file:
for line in file:
if ':' not in line:
line = line.split()
ch1.append([line[0], line[1]])
ch2 = []
with open('ch2.txt', 'r+') as file:
for line in file:
if ':' not in line:
line = line.split()
ch2.append([line[0], line[1]])
然后我遍历两个列表以寻找匹配项。找到匹配项后,我会将右侧列的总和添加到新列表 'coin'
coin = []
for item1 in ch1:
for item2 in ch2:
if item1[0] == item2[0]:
coin.append(int(item1[1]) + int(item2[1]))
问题是这需要很长时间或者崩溃。 运行有没有更高效的方法?
有很多 种方法可以改善这一点;例如:
由于只扫描一次
ch1.txt
的内容,不需要读入列表,占用内存少,但可能不会加快速度。如果对每个列表进行排序,则可以更有效地检查匹配项。类似于:
i1, i2 = 0, 0
while i1 < len(ch1) and i2 < len(ch2):
if ch1[i1][0] == ch2[i2][0]:
# Do what you do for matches
...
# Advance both indices
i1 += 1
i2 += 1
elif ch1[i1][0] < ch2[i2][0]:
# Advance index of the smaller value
i1 += 1
else: # ch1[i1][0] > ch2[i2][0]
i2 += 1
如果文件中的数据已经排序,您可以结合两种想法:而不是推进索引,您只需读取相应文件的下一行。这应该会及时提高效率 and space.
一些改进的想法:
- 以这样的方式将数据存储在字典中,第一列是键,第二列是字典的值供以后使用,
- 一个匹配是如果一个键在两个字典的键的交集
代码示例:
# store your data in dicts as following
ch1_dict[line[0]] = line[1]
ch2_dict[line[0]] = line[1]
#this is what you want to achieve
coin = [int(ch1_dict[key]) + int(ch2_dict[key]) for key in ch1_dict.keys() & ch2_dict.keys()]