Как найти повторяющиеся имена в двух больших файлах? - PullRequest
0 голосов
/ 22 мая 2019

У меня есть два CSV.Одним из них является файл имен.(~ 1000 строк) Другая - это вкладка, разделенная различной информацией о разных людях, в которой в колонке 7 содержатся их имена.(~ 2000000 строк)

Я хочу найти дубликаты имен между этими файлами.

На данный момент я вводю имена из первого файла в список, а затем проверяю строку построка в другом файле, чтобы увидеть, совпадает ли имя строки с любым в списке.Если так, я вывожу это как дубликат.Я знаю, что не оптимально читать построчно 2 миллиона строк, поэтому мне интересно, если бы вы, ребята, сделали что-то другое.

newList = []
otherList = []

with open('listofnames.csv') as f:
    for line in f:
        newList.append(line)

for x in files:
    with open('%s' % x) as f:
        next(f)
        for line in f:
            y = (((line.strip('\n')).split(','))[7]
            if y in newList:
                print(y)

Это напечатало только одно повторяющееся имя 32 раза.

Ответы [ 3 ]

3 голосов
/ 22 мая 2019

Чтение большого файла построчно не является проблемой.Достойные реализации Python (среди них стандартный CPython) обеспечивают буферизацию для файла io, поэтому для чтения большими кусками или построчно требуется одно и то же время, потому что внутренне доступы разбиты на части.

Проблема в том, что поискмного раз (по одному в строке) слово в довольно большом списке, потому что поиск в списке является последовательным, поэтому у вас будет 1000 сравнений, если имя не найдено, и в среднем 500 сравнений, когда оно есть.Было бы намного эффективнее использовать set, потому что набор хэшируется, что разрешает прямой доступ (O (1) вместо O (n))

Поэтому я советую немного изменить ваш код на:

import csv

newlist = set()
otherList = []

with open('listofnames.csv') as f:
    for line in f:
        newList.add(line.strip())

for x in files:
    with open(x) as f:           # no need to format: use directly the filename
        rd = csv.reader(f)       # but rely on a csv.reader to parse a csv file
        next(rd)                 # skip the header line
        for row in rd:
            y = row[7]           # process the right field
            if y in newList:     # searching in a set is fast
                print(y)
1 голос
/ 22 мая 2019

Если вы можете использовать другой пакет, я предлагаю вам использовать пакет панд.

Сначала вы открываете свои файлы с помощью _pd.read_csv ('your_file_name') .Несколько раз используйте merge () function

import pandas as pd 

df1 = pd.read_csv('your_file_name')
df2 = pd.read_csv('your_file_name2')

df1.merge(df2)

Например:

df1 = pd.DataFrame(data = {'Name': ['name1', 'name2', 'name3', 'name4', 'name5', 'name6']})
df2 = pd.DataFrame(data = {'Name': ['name2', 'name3', 'name4',  'name7', 'name8', 'name9']})

In [1] : df1.merge(df2)
Out[2] :    
Name
-------
0   name2
1   name3
2   name4

0 голосов
/ 22 мая 2019

В дополнение к ответу Serges рассмотрите возможность использования функции read_csv от pandas.Как правило, это быстрее, чем анализ вручную, и избавляет вас от выполнения операций зачистки вручную, которые могут вызвать ошибки

(((line.strip('\n')).split(','))[7]

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

Здесьнекоторый пример кода.Вам просто нужно заменить имя файла и имя столбца вашего большого CSV:

import pandas as pd
names = set(pd.read_csv('listofnames.csv').values)
big_file = pd.read_csv('big_file.csv')
duplicates = set(big_file[big_file['column_name_of_column_7'].isin(names)]['column_name_of_column_7'].values)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...