Поиск повторов в нескольких списках, прочитанных из файла CSV (Python)

#python #csv

#python #csv

Вопрос:

Название кажется запутанным, но допустим, я работаю со следующим CSV-файлом (‘names.csv’).

     name1,name2,name3
    Bob,Jane,Joe
    Megan,Tom,Jane
    Jane,Joe,Rob
  

Мой вопрос в том, как мне создать код, который возвращает строку, которая встречается не менее 3 раз. Таким образом, вывод должен быть ‘Jane’, потому что это происходит как минимум 3 раза. Здесь действительно запутался .. возможно, какой-нибудь пример кода поможет мне лучше понять?

Пока у меня есть:

     import csv
    reader = csv.DictReader(open("names.csv"))

    for row in reader:
        names = [row['name1'], row['name2'], row['name3']]
        print names
  

Это возвращает:

     ['Bob', 'Jane', 'Joe']
    ['Megan', 'Tom', 'Jane']
    ['Jane', 'Joe', 'Rob']
  

Что мне делать дальше? Или я ошибаюсь? Я действительно новичок в Python (ну, в программировании в целом), поэтому я почти не представляю, что я делаю..

Приветствия

Ответ №1:

Помещаем это в целом (и показываем правильное использование csv.reader):

 import csv
import collections
d = collections.defaultdict(int)
with open("names.csv", "rb") as f: # Python 3.x: use newline="" instead of "rb"
    reader = csv.reader(f):
    reader.next() # ignore useless heading row
    for row in reader:
        for name in row:
            name = name.strip()
            if name:
                d[name]  = 1
 morethan3 = [(name, count) for name, count in d.iteritems() if count >= 3]
 morethan3.sort(key=lambda x: x[1], reverse=True)
 for name, count in morethan3:
    print name, count
  

Обновить в ответ на комментарий:

Вам нужно прочитать весь CSV-файл, независимо от того, используете вы подход DictReader или нет. Если вы хотите, например, игнорировать столбец ‘name2’ (не строку), то игнорируйте его. Вам не нужно сохранять все данные, как предполагает использование имени переменной «rows». Вот код для более общего подхода, который не зависит от того, что заголовки столбцов расположены в определенном порядке, и позволяет выбирать / отклонять определенные столбцы.

     reader = csv.DictReader(f):
    required_columns = ['name1', 'name3'] #### adjust this line as needed ####
    for row in reader:
        for col in required_columns:
            name = row[col].strip()
            if name:
                d[name]  = 1
  

Комментарии:

1. Спасибо! Это работает действительно хорошо, но поскольку вы проигнорировали строку заголовка, он считывает весь CSV-файл.. Что, если бы я хотел подсчитать, сколько раз определенное имя встречается только в 2 из 3 строк в файле CSV? т. Е. Файл CSV содержит ‘name1’, ‘name2’, ‘name3’, но я хочу подсчитывать имена только в строках ‘name1’ и ‘name3’, таким образом, полностью игнорируя строку ‘name2’..

2. В этом есть БОЛЬШОЙ смысл. Я, наконец, понял это сейчас. 🙂 Еще раз спасибо

Ответ №2:

Я бы сделал это так:

 >>> from collections import defaultdict
>>> d = defaultdict(int)
>>> rows = [['Bob', 'Jane', 'Joe'],
... ['Megan', 'Tom', 'Jane'],
... ['Jane', 'Joe', 'Rob']]
...
>>> for row in rows:
...     for name in row:
...         d[name]  = 1
... 
>>> filter(lambda x: x[1] >= 3, d.iteritems())
[('Jane', 3)]
  

Он использует dict со значением по умолчанию 0, чтобы подсчитать, сколько раз каждое имя встречается в файле, а затем фильтрует dict с соответствующим условием (count >= 3).