我在csv文件中有一个大约7000个名字的列表,这些名字按姓氏,姓名,出生日期等排列。我还有一个大约7000多个扫描文件(登记表格)的文件夹,每个文件的名称都是人作为文件名。
现在文件名可能与csv中的名称不完全匹配。约翰·多伊在csv,文件名将是John-Michael Doe等。
我如何编写一个通过csv查看的程序,看看扫描文件夹中缺少哪些文件名?
我是编程方面的新手,任何建议都表示赞赏。
答案 0 :(得分: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'}
...]
接下来,您希望使用os.listdir
import os
images_directory = '/path/to/images/'
image_paths = [
os.path.join(images_directory, filename)
for filename in os.listdir(images_directory)]
现在您需要某种方法从文件中提取名称。这在很大程度上取决于文件的结构方式。用于此任务的棘手使用但功能非常强大的工具称为正则表达式,但可能只需要一些简单的就足够了。例如,如果文件名为“first-name last-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,而“哑”启发式可能会捕获其中的大多数。如果您需要更高级的启发式方法,可以查看名称中“{3”}的Jaccard similarity和difflib模块以进行近似字符串匹配。
当然,大部分代码都不会完全处理您的问题,但希望它足以帮助您入门。