基于群集对应列表对图像进行排序

时间:2017-06-11 10:57:18

标签: python sorting cluster-computing

我有以下工作代码来根据群集列表对图像进行排序,群集列表是元组列表:#include <cstring.h>
一个图像只能在一个且只有一个集群中(例如,在两个集群中从不存在相同的图像)。

我想知道是否有办法缩短&#34; for + for + if + if&#34;在代码末尾循环,对于每个文件名,我必须检查群集列表中的每一对,这使它有点多余。

(image_id, cluster_id)

当然,因为我对Python很陌生,所以欢迎任何其他很好解释的改进!

1 个答案:

答案 0 :(得分:1)

我认为你的复杂程度远远超过了需要。由于您的图片名称是唯一的(只能有一个image_id),因此您可以安全地将pts_cls转换为dict并在现场快速查找,而不是循环遍历每个对的列表每一次。您也正在使用不需要的正则表达式,并且您只是打包路径,以便稍后解压缩。

此外,如果您的源目录中的图片不在pts_cls中,因为其outdir永远不会被设置(或者更糟,其outdir是前一个循环中的一个。)

我简化了它:

import os
import shutil

src_dir = "/home/username/pictures/"

if not os.path.isdir(src_dir):
    print("Error, %s is not a valid directory!" % src_dir)
    exit(1)  # return is expected only from functions

pts_cls = []  # is the list of pairs (image_id, cluster_id), load from whereever...

# convert your pts_cls into a dict - since there cannot be any images in multiple clusters
# base image name is perfectly ok to use as a key for blazingly fast lookups later
cluster_map = dict(pts_cls)

# get only `.jpg` files; store base name and file name, no need for a full path at this time
files = [(fn[:-4], fn) for fn in os.listdir(src_dir) if fn.lower()[-4:] == ".jpg"]
# no need for sorting based on your code

for name, file_name in files:  # loop through all files
    if name in cluster_map:  # proceed with the file only if in pts_cls
        cls = cluster_map[name]  # get our cluster value
        # get our `cluster_<cluster_id>` or `cluster_Noise` (if cluster == -1) target path
        target_dir = os.path.join(src_dir, "cluster_" + str(cls if cls != -1 else "Noise"))
        target_file = os.path.join(target_dir, file_name)  # get the final target path
        if not os.path.exists(target_file):  # if the target file doesn't exists
            if not os.path.isdir(target_dir):  # make sure our target path exists
                os.makedirs(target_dir, exist_ok=True)  # create a full path if it doesn't
            shutil.copy(os.path.join(src_dir, file_name), target_file)  # copy

更新 - 如果您有多个&#39;特殊&#39;某些群集ID的文件夹(例如Noise适用于-1)您可以创建一个类似cluster_targets = {-1: "Noise"}的地图,其中的密钥是您的群集ID,其值显然是特殊的名称。然后,您可以将target_dir代替换为:target_dir = os.path.join(src_dir, "cluster_" + str(cluster_targets.get(cls,cls)))

更新#2 - 由于您的image_id值似乎是整数,而文件名是字符串,我建议您只构建cluster_map {{1通过将dict部分转换为字符串。这样你就可以在不存在类型不匹配危险的情况下将喜欢与喜欢进行比较:

image_id

如果您确定cluster_map = {str(k): v for k, v in pts_cls} 中的* .jpg文件中没有一个名称中包含非整数,则可以将文件名转换为整数,以{src_dir开头。 1}}列表生成 - 只需将files替换为fn[:-4]。但我不建议再说一次,你永远不知道你的文件是如何被命名的。