我试图在Python中首次出现CSV的每一行。但是,我遇到了一个问题。我的CSV文件如下所示:
1,2,3,a,7,5,y,0
1,2,3,a,3,5,y,8
1,2,3,a,5,3,y,7
1,2,3,d,7,5,n,0
1,2,3,d,3,5,n,8
1,2,3,d,5,3,n,7
2,3,4,f,4,6,y,9
2,3,4,f,5,6,y,9
2,3,4,f,7,3,y,9
2,3,4,e,3,5,n,9
2,3,4,e,0,7,n,9
2,3,4,e,5,8,n,9
我尝试这种方式来获得基于其中一列的第一次出现的唯一值。
def unique():
rows = list(csv.reader(open('try.csv', 'r'), delimiter=','))
columns = zip(*rows)
uniq = set(columns[1])
indexed = defaultdict(list)
for x in uniq:
i = columns[1].index(x)
indexed[i] = rows[i]
return indexed
它适用于一个唯一的列值集。但是,
1,2,3,d,7,5,n,0,a 2,3,4,e,3,5,n,9,f
答案 0 :(得分:3)
您的代码还有一些改进空间,但我不想深入重写它,因为您几乎正确。 “关键”一点是你需要一个复合键。这是对 (r[1],r[6])
必须是唯一的。此外,我冒昧地使用OrderedDict
进行快速查找,但保留了行顺序。
import csv
import collections
def unique():
rows = list(csv.reader(open('try.csv', 'r'), delimiter=','))
result = collections.OrderedDict()
for r in rows:
key = (r[1],r[6]) ## The pair (r[1],r[6]) must be unique
if key not in result:
result[key] = r
return result.values()
from pprint import pprint
pprint(unique())
产:
[['1', '2', '3', 'a', '7', '5', 'y', '0'],
['1', '2', '3', 'a', '7', '5', 'n', '0'],
['2', '3', '4', 'f', '4', '6', 'y', '9'],
['2', '3', '4', 'f', '3', '5', 'n', '9']]
答案 1 :(得分:1)
这是一个替代实现。
从数据集中读入每一行。我们使用defaultdict(list)
来存储所有行,基于每行两列索引。当从数据集中读入一行时,它会根据该行的两列索引键附加到defaultdict
。
最后,我们浏览defaultdict
。我们希望匹配索引的数据集中的 first 行,因此我们返回对应于两列索引的uniq[0]
。
import csv
from collections import defaultdict
def unique():
uniq = defaultdict(list)
for row in csv.reader(open('try.csv', 'r'), delimiter=','):
uniq[ (row[0],row[6]) ].append(row)
for idx,row in uniq.iteritems():
yield row[0]
print list( unique() )
[['2', '3', '4', 'f', '4', '6', 'y', '9'], ['2', '3', '4', 'f', '3', '5', 'n', '9'], ['1', '2', '3', 'a', '7', '5', 'y', '0'], ['1', '2', '3', 'a', '7', '5', 'n', '0']]
答案 2 :(得分:0)
旧主题,但可能对其他有用:如果您在Unix环境中,为什么不调用外部uniq
命令?这样你就不必重新发明这些代码,并从可能更好的性能中受益。