我有两个CSV。 一个是名称文件。 (〜1000行) 另一个是制表符,该制表符用关于不同人员的各种信息定界,其中第7列保留了其名称。 (〜2000000行)
我想在这些文件之间找到重复的名称。
到目前为止,我正在将第一个文件中的名称输入到列表中,然后逐行检查另一个文件中的名称,以查看该行的名称是否与列表中的任何名称匹配。如果是这样,我将其输出为重复项。我知道逐行读取200万行不是最佳选择,所以我想知道你们是否会做一些不同的事情。
newList = []
otherList = []
with open('listofnames.csv') as f:
for line in f:
newList.append(line)
for x in files:
with open('%s' % x) as f:
next(f)
for line in f:
y = (((line.strip('\n')).split(','))[7]
if y in newList:
print(y)
它只打印出32个重复名称。
答案 0 :(得分:3)
逐行读取大文件不是问题。体面的Python实现(其中包括标准CPython)在文件io上提供了缓冲,因此,由于内部访问是分块的,因此需要大块或逐行读取相同的时间。
有问题的是在一个相当大的列表中多次搜索(每行一次)一个单词,因为列表中的搜索是连续的,因此如果找不到名称,则将有1000次比较,而在没有名称的情况下平均有500次比较它是。使用set
会更有效率,因为对集合进行哈希处理可以直接访问(O(1)而不是O(n))
所以我的建议是将您的代码稍微更改为:
import csv
newlist = set()
otherList = []
with open('listofnames.csv') as f:
for line in f:
newList.add(line.strip())
for x in files:
with open(x) as f: # no need to format: use directly the filename
rd = csv.reader(f) # but rely on a csv.reader to parse a csv file
next(rd) # skip the header line
for row in rd:
y = row[7] # process the right field
if y in newList: # searching in a set is fast
print(y)
答案 1 :(得分:0)
除了Serges答案外,还考虑使用熊猫的read_csv函数。通常,这比手动解析要快,并且可以避免进行容易引起错误的手动剥离操作
(((line.strip('\n')).split(','))[7]
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html
这是一些示例代码。您只需要替换大型csv的文件名和列名即可:
import pandas as pd
names = set(pd.read_csv('listofnames.csv').values)
big_file = pd.read_csv('big_file.csv')
duplicates = set(big_file[big_file['column_name_of_column_7'].isin(names)]['column_name_of_column_7'].values)
答案 2 :(得分:0)
如果可以使用其他软件包,建议您使用pandas软件包。
首先,您使用 _pd.read_csv('your_file_name')打开文件。 其次使用 merge()函数
import pandas as pd
df1 = pd.read_csv('your_file_name')
df2 = pd.read_csv('your_file_name2')
df1.merge(df2)
示例:
df1 = pd.DataFrame(data = {'Name': ['name1', 'name2', 'name3', 'name4', 'name5', 'name6']})
df2 = pd.DataFrame(data = {'Name': ['name2', 'name3', 'name4', 'name7', 'name8', 'name9']})
In [1] : df1.merge(df2)
Out[2] :
Name
-------
0 name2
1 name3
2 name4