我已经列出了一个由姓氏,姓名,出生日期等排列的csv文件中的大约7000个名字。我还有一个大约7000+个扫描文档的文件夹注册表格),其中每个人的名字都是文件名。匹配csv文件中的文件名到文件夹中的文件名
现在,文件名可能与csv中的名称不完全匹配。 John Doe在csv中的文件名将是John-Michael Doe等。
我该如何编写一个程序,通过csv查看并查看扫描的文件夹中缺少哪些文件名?
我是一个完全新手编程和任何意见表示赞赏。
我已经列出了一个由姓氏,姓名,出生日期等排列的csv文件中的大约7000个名字。我还有一个大约7000+个扫描文档的文件夹注册表格),其中每个人的名字都是文件名。匹配csv文件中的文件名到文件夹中的文件名
现在,文件名可能与csv中的名称不完全匹配。 John Doe在csv中的文件名将是John-Michael Doe等。
我该如何编写一个程序,通过csv查看并查看扫描的文件夹中缺少哪些文件名?
我是一个完全新手编程和任何意见表示赞赏。
您想要做的第一件事就是将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模块。
当然这个代码大部分不会相当工作在你的问题上,但希望它足以让你开始。
看这个的一种方法是制作两个集合,一个来自csv的(姓名),另一个从文件名中提取(通过拆分等)。除非你有一个一致的命名约定,否则你不会有完整的匹配,但是这应该让你头痛得多:) – sal
作为编程的完全新手,你可能会发现这个教程很有用:https://www.dataquest.io /你需要做一些事情,比如读取文件夹中的文件名,辨别正则表达式,考虑“bigO”策略来检查列表等。把它分解成小部分并继续黑客入侵,祝你好运! –