2012-02-12 2 views
4

Я только начал изучать python. Мне интересно, какие эффективные способы подсчета появления определенного слова в CSV-файле, а не просто использовать для цикла, чтобы идти по строке за строкой и читать.Python алгоритм подсчета появления конкретного слова в csv

Чтобы быть более конкретным, допустим, что у меня есть файл CSV, содержащий два столбца: «Имя» и «Оценка», с миллионами записей.

Как можно считать появление «А» под «Оценка»?

Примеры кода на Python были бы очень признательны!

+3

Вы должны прочитать весь файл, в противном случае ваш алгоритм может оказаться неверным. Читая его линейно, по строкам, это не плохой подход. – bdares

+2

'import csv; count = sum (1 для строки в csv.dictreader (open (filename)), если строка ['Grade'] == 'A') ' – agf

+0

@agf: приятно, но когда я пробовал это, это был фактор 6- 8 медленнее, чем другие ответы – steabert

ответ

7

Простой пример, с помощью csv и collections.Counter (Python 2.7+) из стандартного Python libraly:

import csv 
import collections 

grades = collections.Counter() 
with open('file.csv') as input_file: 
    for row in csv.reader(input_file, delimiter=';'): 
     grades[row[1]] += 1 

print 'Number of A grades: %s' % grades['A'] 
print grades.most_common() 

Output (для малого набора данных):

Number of A grades: 2055 
[('A', 2055), ('B', 2034), ('D', 1995), ('E', 1977), ('C', 1939)] 
+0

ОК, но вы можете применить 'Counter' к выражению генератора для первого элемента строк в файле – steabert

+0

Спасибо! Я принял ваш ответ. Но мне было интересно сравнить это с использованием словаря, с классом как ключом и возникновением в качестве значения, что будет более эффективным? – laotanzhurou

+0

@laotanzhurou, 'Counter' является подклассом' dict', но он немного медленнее. Если вам действительно нужно ускорить ['collections.defaultdict (int)'] (http://docs.python.org/dev/library/collections.html#collections.defaultdict) или 'if ... count + = 1' вероятно будет быстрее. Но вы всегда можете сравнить его с помощью [timeit] (http://docs.python.org/library/timeit.html), см. _Johnsyweb's_ [ответ] (http://stackoverflow.com/a/9247545/ 1052325) – reclosedev

0

Вы должны, конечно, прочитать все классы, которые в этом случае также означают чтение всего файла. Вы можете использовать csv модуль легко читать через запятую файлы значений:

import csv 
my_reader = csv.reader(open('my_file.csv')) 
ctr = 0 
for record in my_reader: 
    if record[1] == 'A': 
     ctr += 1 
print(ctr) 

Это довольно быстро, и я не мог бы сделать лучше с помощью метода Counter:

from collections import Counter 
grades = [rec[1] for rec in my_reader] # generator expression was actually slower 
result = Counter(grades) 
print(result) 

И последнее, но не в последнюю очередь, списки имеют count метод:

from collections import Counter 
grades = [rec[1] for rec in my_reader] 
result = grades.count('A') 
print(result) 
2

Как вы уже видели, существует целый ряд способов решения этой проблемы.

Лучший способ оценить их скорость - это время, используя timeit. Например:

% python -m timeit -c 'import csv 
with open("./grades.csv") as grades: 
    table = csv.DictReader(grades) 
    sum(1 for row in table if row["Grade"] == "A")  
' 
10000 loops, best of 3: 129 usec per loop 
Смежные вопросы