2016-09-21 89 views
0

我已经列出了一个由姓氏,姓名,出生日期等排列的csv文件中的大约7000个名字。我还有一个大约7000+个扫描文档的文件夹注册表格),其中每个人的名字都是文件名。匹配csv文件中的文件名到文件夹中的文件名

现在,文件名可能与csv中的名称不完全匹配。 John Doe在csv中的文件名将是John-Michael Doe等。

我该如何编写一个程序,通过csv查看并查看扫描的文件夹中缺少哪些文件名?

我是一个完全新手编程和任何意见表示赞赏。

+0

看这个的一种方法是制作两个集合,一个来自csv的(姓名),另一个从文件名中提取(通过拆分等)。除非你有一个一致的命名约定,否则你不会有完整的匹配,但是这应该让你头痛得多:) – sal

+0

作为编程的完全新手,你可能会发现这个教程很有用:https://www.dataquest.io /你需要做一些事情,比如读取文件夹中的文件名,辨别正则表达式,考虑“bigO”策略来检查列表等。把它分解成小部分并继续黑客入侵,祝你好运! –

回答

0

您想要做的第一件事就是将CSV读取到内存中。你可以用csv module来做到这一点。最有用的工具有csv.DictReader,这需要的文件在字典中键的第一行,并读取余数为:

import csv 
with open('/path/to/yourfile.csv', 'r') as f: 
    rows = list(csv.DictReader(f)) 

from pprint import pprint 
pprint(rows[:100]) 

在Windows中,路径看起来不同,会是这样的c:/some folder/some other folder/(注意前斜杠而不是反斜杠)。

这将显示文件的前100行。例如,如果你有一个名为列“名”,“姓”,“出生日期”,这将是这样的:

[{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'}, 
{'Date of Birth': 'Jan 1, 1970', 'First Name': 'John', 'Last Name': 'Doe'} 
...] 

接下来,你要得到所有的7000个文件的列表,使用os.listdir

import os 
images_directory = '/path/to/images/' 
image_paths = [ 
    os.path.join(images_directory, filename) 
    for filename in os.listdir(images_directory)] 

现在您需要一些方法从文件中提取名称。这关键取决于文件的结构。这个任务使用棘手的但非常强大的工具称为正则表达式,但可能是简单的东西就足够了。例如,如果文件被命名为喜欢“直呼其名的最后name.pdf”,你可以写一个简单的分析方法,如:

def parse_filename(filename): 
    name, extension = filename.split('.') 
    first_name, last_name = name.split(' ') 
    return first_name.replace('-', ' '), last_name.replace('-', ' ') 

确切的实施将取决于文件的命名方式,但关键的事情,让你开始是str.split,str.strip和在同一类别的一些其他人。你也可以看看re module for handling regular expressions。正如我所说,这是一种更先进/强大的技术,所以现在可能不值得担心。

一种简单的方法做匹配会像下面这样:

name_to_filename = {parse_filename(filename.lower()): filename for filename in filenames} 
matched_rows = [] 
unmatched_files = [] 
for row in rows: 
    name_key = (row['First Name'].lower(), row['Last Name'].lower()) 
    matching_file = name_to_filename.get(name_key) # This sees if we have a matching file name, and returns 
                # None otherwise. 
    new_row = row.copy() 
    if matching_file: 
     new_row['File'] = matching_file 
     print('Matched "%s" to %s' % (' '.join(name_key), matching_file)) 
    else: 
     new_row['File'] = '' 
     print('No match for "%s"' % (' '.join(name_key))) 
    matched_rows.append(new_row) 
with open('/path/to/output.csv', 'w') as f: 
    writer = csv.DictWriter(f, ['First Name', 'Last Name', 'Date of Birth', 'File]) 
    writer.writeheader() 
    writer.writerows(matched_rows) 

这应该给你什么你行可以匹配自动匹配起来,其余的空白输出电子表格。根据数据的干净程度,您可能只能手动匹配剩余的几个条目。只有7000人,“愚蠢”的启发式可能会吸引大部分人。如果您需要更高级的启发式方法,则可以查看名称中的“单词”的Jaccard similarity以及用于近似字符串匹配的difflib模块。

当然这个代码大部分不会相当工作在你的问题上,但希望它足以让你开始。

相关问题