Skip to main content
 首页 » 编程设计

python之Python itertools groupby 中令人不安的奇怪行为/错误

2025年05月04日10Free-Thinker

我正在使用 itertools.groupby 来解析一个简短的制表符分隔的文本文件。文本文件有几列,我想做的就是将具有特定值 x 的所有条目分组到特定列中。下面的代码对名为 name2 的列执行此操作,查找变量 x 中的值。我尝试使用 csv.DictReader 和 itertools.groupby 来做到这一点。在表中,有 8 行符合此条件,因此应返回 8 个条目。相反,groupby 返回两组条目,一组有一个条目,另一组有 7 个条目,这似乎是错误的行为。我在下面对相同的数据手动进行匹配并得到正确的结果:

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 获取一组条目,但它返回了两个。我想不通。 编辑:啊知道了,应该对其进行排序。

请您参考如下方法:

您将要更改代码以强制数据按键顺序...

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)