2012-10-24 2 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()은 동일한 키의 연속 어커런스만을 그룹화합니다.

당신은 키 순서로 데이터를 강제로 코드를 변경하려는거야