2012-10-24 28 views
1

我正在使用itertools.groupby解析制表符分隔的短文本文件。该文本文件有几列,我想要做的就是将特定列中具有特定值x的所有条目分组。下面的代码对于名为name2的列执行此操作,查找变量x中的值。我试图用csv.DictReaderitertools.groupby来做到这一点。在表中,有行符合这个标准,所以应该返回8个条目。相反,groupby返回两组条目,一个条目为单条,另一条条目为7,这看起来是错误的行为。我在相同的数据匹配手动下方得到正确的结果:扰乱python itertools groupby中的奇怪行为/错误?

import itertools, operator, csv 
col_name = "name2" 
x = "ENSMUSG00000002459" 
print "looking for entries with value %s in column %s" %(x, col_name) 
print "groupby gets it wrong: " 
data = csv.DictReader(open(f), delimiter="\t", fieldnames=fieldnames) 
for name, entries in itertools.groupby(data, key=operator.itemgetter(col_name)): 
    if name == "ENSMUSG00000002459": 
     wrong_result = [e for e in entries] 
     print "wrong result has %d entries" %(len(wrong_result)) 
print "manually grouping entries is correct: " 
data = csv.DictReader(open(f), delimiter="\t", fieldnames=fieldnames) 
correct_result = [] 
for row in data: 
    if row[col_name] == "ENSMUSG00000002459": 
     correct_result.append(row) 
print "correct result has %d entries" %(len(correct_result)) 

我得到的输出是:

looking for entries with value ENSMUSG00000002459 in column name2 
groupby gets it wrong: 
wrong result has 7 entries 
wrong result has 1 entries 
manually grouping entries is correct: 
correct result has 8 entries 

这到底是怎么回事呢?如果groupby确实是分组,那么看起来我应该只按x获得一组条目,但是它返回两个。我无法弄清楚这一点。 编辑:啊,它应该排序。

+0

这是关于'GROUPBY如何'()''的作品,但它是记录的行为,我建议一种常见的误解你更仔细地阅读文档。 –

回答

3

你会想改变你的代码,迫使该数据是根据索引顺序...

data = csv.DictReader(open(f), delimiter="\t", fieldnames=fieldnames) 
sorted_data = sorted(data, key=operator.itemgetter(col_name)) 
for name, entries in itertools.groupby(data, key=operator.itemgetter(col_name)): 
    pass # whatever 

主要用途虽然是当数据集大,数据已经按键的顺序,所以当你无论如何都要进行排序,然后使用defaultdict更有效

from collections import defaultdict 
name_entries = defaultdict(list) 
for row in data: 
    name_entries[row[col_name]].append(row) 
3

根据相同的密钥的documentation,只有groupby()组连续出​​现。