我已經列出了一個由姓氏,姓名,出生日期等排列的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」策略來檢查列表等。把它分解成小部分並繼續黑客入侵,祝你好運! –