从CSV文件中提取不重复的列表

1 投票
3 回答
613 浏览
提问于 2025-04-18 04:07

我有一个数据集,内容大概是这样的:

id,created_at,username
1,2006-10-09T18:21:51Z,hey
2,2007-10-09T18:30:28Z,bob
3,2008-10-09T18:40:33Z,bob
4,2009-10-09T18:47:42Z,john
5,2010-10-09T18:51:04Z,brad
...

这个数据集有超过100万行。

我想用Python从中提取出不重复的用户名列表。目前我的代码是这样的:

import csv

file1 = file("sample.csv", 'r')
file2 = file("users.csv", 'w')

reader = csv.reader(file1)
writer = csv.writer(file2)

rownum = 0
L = []
for row in reader:
    if not rownum == 0:
        if not row[2] in L:
            L.append(row[2])
            writer.writerow(row[2])

    rownum += 1

我有几个问题:

1 - 我在users.csv文件里的输出结果是这样的:

h,e,y
b,o,b
j,o,h,n
b,r,a,d

我该怎么去掉每个字母之间的逗号呢?

2 - 我的代码看起来不太优雅,有没有办法把csv文件导入成一个矩阵,然后选择最后一行,再用像JavaScript里的underscore.js这样的优雅库来去重呢?

非常感谢!

3 个回答

-1

简单又快捷!

for line in reader:
    string = str(line)
    split = string.split("," , 2)
    username = split[2][2:-2]
0

更改

writer.writerow(row[2])

writer.writerow([row[2]])

另外,检查一个项目是否在列表中是比较耗费计算资源的,复杂度是 [O(n)]。如果你需要在一个很大的项目集合中频繁检查某个项目是否存在,建议使用 set,它的复杂度是 [O(1)]:

L = set()
reader.next() # Skip the header
for row in reader:
    if row[2] not in L:
        L.add(row[2])
        writer.writerow([row[2]])

另外

如果你可以接受使用几兆字节的内存,可以这样做:

with open("sample.csv", "rb") as infile:
    reader = csv.reader(infile)
    reader.next()
    no_duplicates = set(tuple(row) for row in reader)

    with open("users.csv", "wb") as outfile:
        csv.writer(outfile).writerows(no_duplicates)

如果顺序很重要,建议使用 OrderedDict 而不是 set:

from collections import OrderedDict
with open("sample.csv", "rb") as infile:
    reader = csv.reader(infile)
    reader.next()
    no_duplicates = OrderedDict.fromkeys(tuple(row) for row in reader)

    with open("users.csv", "wb") as outfile:
        csv.writer(outfile).writerows(no_duplicates.keys())
5

你可以在这里使用一个 set,它在查找某个项目时的速度是 O(1),而列表的查找速度是 O(N),也就是说,使用 set 会更快。

seen = set()
add_  = seen.add
next(reader) #skip header
writer.writerows([row[-1]] for row in reader if row[-1] not in seen
                                                        and not add_(row[-1]))

而且处理文件时,记得总是使用 with 语句,这样它会自动帮你关闭文件:

with file("sample.csv", 'r') as file1, file("users.csv", 'w') as file2:
    #Do stuff with file1 and file2 here

撰写回答