簡體   English   中英

根據文件名加速文件匹配

[英]Speed up file matching based on names of files

因此我有2個目錄,其中包含2種不同的文件類型(例如.csv,.png),但具有相同的基本名稱(例如1001_12_15.csv,1001_12_15.png)。 每個目錄中都有成千上萬個文件。

我想要做的是在匹配基本名稱之后獲取文件的完整路徑,然后使用兩個文件的完整路徑進行操作。

我在尋求有關如何加快程序的幫助。

我的方法是:

csvList=[a list with the full path of each .csv file]
pngList=[a list with the full path of each .png file]



for i in range(0,len(csvlist)):
    csv_base = os.path.basename(csvList[i])
    #eg 1001
    csv_id = os.path.splitext(fits_base)[0].split("_")[0]

    for j in range(0, len(pngList)):
        png_base = os.path.basename(pngList[j])
        png_id = os.path.splitext(png_base)[0].split("_")[0]
        if float(png_id) == float(csv_id):
            DO SOMETHING

此外,我嘗試了fnmatch之類的東西:

for csv_file in csvList:
    try:
        csv_base = os.path.basename(csv_file)

        csv_id = os.path.splitext(csv_base)[0].split("_")[0]

        rel_path = "/path/to/file"
        pattern = "*" + csv_id + "*.png"

        reg_match = fnmatch.filter(pngList, pattern)
        reg_match=" ".join(str(x) for x in reg_match)
        if reg_match:
            DO something

似乎使用嵌套的for循環更快。 但我希望它更快。 還有其他可以加快代碼執行速度的方法嗎?

首先,像這樣優化現有循環中的語法

for csv in csvlist:
    csv_base = os.path.basename(csv)
    csv_id = os.path.splitext(csv_base)[0].split("_")[0]

    for png in pnglist:
        png_base = os.path.basename(png)
        png_id = os.path.splitext(png_base)[0].split("_")[0]
        if float(png_id) == float(csv_id):
            #do something here

嵌套循環非常慢,因為您需要運行png循環n2次

然后,您可以使用列表推導數組索引來加快速度

## create lists of processed values 
## so you dont have to keep running the os library
sv_base_list=[os.path.basename(csv) for csv in csvlist]
csv_id_list=[os.path.splitext(csv_base)[0].split("_")[0] for csv_base in csv_base_list]
png_base_list=[os.path.basename(png) for png in pnglist]
png_id_list=[os.path.splitext(png_base)[0].split("_")[0] for png_base in png_base_list]


## run a single loop with list.index to find matching pair and record base values array

csv_png_base=[(csv_base_list[csv_id_list.index(png_id)], png_base)\
                   for png_id,png_base in zip(png_id_list,png_base_list)\
                   if png_id in csv_id_list]

## csv_png_base contains a tuple contianing (csv_base,png_base)
  • 使用列表索引的此邏輯大大減少了循環計數,並且沒有重復的os lib調用
  • 列表理解比普通循環快一點

您可以遍歷列表並使用值進行某些操作,例如

for csv_base,png_base in csv_png_base:
    #do something

熊貓會更快地完成這項工作,因為它將使用C庫運行循環

您可以在O(n)中建立搜索索引,然后在O(1)中分別搜索其中的項目。 如果您的問題完全符合您的要求,則平整查詢dict就足夠了:

from os.path import basename, splitext

png_lookup = {
    splitext(basename(png_path))[0] : png_path
    for png_path in pngList
}

這使您可以直接查找與每個csv文件相對應的png文件:

for csv_file in csvList:
    csv_id = splitext(basename(csv_file)[0]
    try:
        png_file = png_lookup[csv_id]
    except KeyError:
        pass
    else:
        # do something

最后,您將獲得一個O(n)查找結構以及一個帶有嵌套O(1)查找的單獨O(n)迭代。 與您的初始O(n ^ 2)相比,總復雜度為O(n)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM