我有一个大的CSV文件,我从中读取一些数据并将该数据添加到字典中。我的CSV文件大约有360000行,我的字典长度只有5700.我知道我的CSV有很多重复项,但我希望大约有50000行。我知道Python字典对大小没有限制。我的代码读取文件中的所有360000个条目,将其写入另一个文件并终止。所有这些处理在大约2秒内完成,没有任何例外。我如何确定我处理的CSV中的所有项目实际上都已添加到字典中?
我使用的代码如下:
with open("read.csv", 'rb') as input1:
with open("write.csv", 'wb') as output1:
reader = csv.reader(input1, delimiter="\t")
writer = csv.writer(output1, delimiter="\t")
#Just testing if my program reads the whole CSV file
for row in reader:
count += 1
print count # Gives 360000
input1.seek(0)
for row in reader:
#print row[1] + "\t" + row[2]
dict1.update({row[1] : [ row[2], row[0] ]})
print len(dict1) # Gives 5700
for key in dict1:
ext_id = key
list1 = dict1[key]
name = list1[0]
url = list1[1]
writer.writerow([ext_id, name, url])
修改
我不确定人们是否理解我想要做什么以及这将如何相关,但我仍然会解释。
我的CSV文件每行有3列。他们的格式如下:
URL+unique value | unique value | some name
但是,这些行在CSV中是重复的,我想要另一个只有行没有任何副本的CSV。
答案 0 :(得分:3)
词典中的键是row[1]
。字典的大小取决于输入中此字段的不同值。行(row[2], row[0]
)的其余部分在行之间是否不同并不重要。
示例:
a,foo,1
b,bar,2
c,foo,3
d,baz,4
如果第一个字段(索引3
)用作键,将导致长度为1
的字典。结果将是:
{'foo':['3', 'c'],
'bar':['2', 'b'],
'baz':['4', 'd']}
第一行将被覆盖。当然,“订单”可能会有所不同,因为字典没有订单。
答案 1 :(得分:2)
编辑:如果您只是检查唯一性,则无需将其放入字典(专为快速查找和分组而设计)中。请改用此处set
。
out_ = set()
for row in reader:
out_.add(tuple(row))
# csv.reader may iterate through tuples already, I don't know! If so
# there's obviously no reason to cast it as one. Do:
## print(type(reader[0]))
# to find out.
for row in out_:
writer.writerow([row[1], row[0], row[2]])
这是我能想到的最快的检查。
set_headers = {row[1] for row in reader}
这是一个包含CSV中所有行的所有第2列(也就是row[1]
)的集合。您可能知道,集合不能包含重复项,因此这将为您提供每行标题列中的UNIQUE值。
自dict.update
替换值以来,这正是您将len(dict1)
看到的,实际上是len(set_headers) == len(dict1)
。每次迭代一行时,dict.update
都会将密钥row[1]
的值更改为(row[0], row[2])
。如果你不关心早期的价值观,那可能就好了,但我不认为这是真的。
相反,这样做:
for row in reader:
dict1.setdefault(row[1],[]).append((row[0],row[1]))
这将最终成为:
dict1 = {"foo": [(row1_col0,row1_col2),(row3_col0,row3_col2)],
"baz": [(row2_col0,row2_col2)]}
来自输入:
row1_col0, foo, row1_col2
row2_col0, baz, row2_col2
row3_col0, foo, row3_col2
现在你可以这样做,例如:
for header in dict1:
for row in header:
print("{}\t{}".format(row[0],row[1]))
答案 2 :(得分:1)
确保获得所有内容的最简单方法是添加2个测试列表。添加:test1,test2 = [],[],然后在更新字典后立即添加test1.append(row [1]),然后如果row [1]不在test2中:test2.append(row [1])。然后你可以打印两个列表的长度,看看test2的长度是否与你的字典相同,test1的长度和输入csv的长度相同。
with open("read.csv", 'rb') as input1:
with open("write.csv", 'wb') as output1:
reader = csv.reader(input1, delimiter="\t")
writer = csv.writer(output1, delimiter="\t")
#Just testing if my program reads the whole CSV file
test1,test2=[],[]
for row in reader:
count += 1
print count # Gives 360000
input1.seek(0)
for row in reader:
#print row[1] + "\t" + row[2]
dict1.update({row[1] : [ row[2], row[0] ]})
test1.append(row[1])
if row[1] not in test2: test2.append(row[1])
print 'dictionary length:', len(dict1) # Gives 5700
print 'test 1 length (total values):',len(test1)
print 'test2 length (unique key values):',len(test2)
for key in dict1:
ext_id = key
list1 = dict1[key]
name = list1[0]
url = list1[1]
writer.writerow([ext_id, name, url])