Python 基于群集对应列表对图像进行排序
我有以下工作代码来根据一个集群列表(一个元组列表)对图像进行排序:Python 基于群集对应列表对图像进行排序,python,sorting,cluster-computing,Python,Sorting,Cluster Computing,我有以下工作代码来根据一个集群列表(一个元组列表)对图像进行排序:(image\u id,cluster\u id) 一个图像只能在一个簇中,也只能在一个簇中(例如,两个簇中永远不会有相同的图像) 我想知道是否有办法缩短代码末尾的“for+for+if+if”循环。到目前为止,对于每个文件名,我必须检查集群列表中的每一对,这使得它有点多余 import os import re import shutil srcdir = '/home/username/pi
(image\u id,cluster\u id)
一个图像只能在一个簇中,也只能在一个簇中(例如,两个簇中永远不会有相同的图像) 我想知道是否有办法缩短代码末尾的“for+for+if+if”循环。到目前为止,对于每个文件名,我必须检查集群列表中的每一对,这使得它有点多余
import os
import re
import shutil
srcdir = '/home/username/pictures/' #
if not os.path.isdir(srcdir):
print("Error, %s is not a valid directory!" % srcdir)
return None
pts_cls # is the list of pairs (image_id, cluster_id)
filelist = [(srcdir+fn) for fn in os.listdir(srcdir) if
re.search(r'\.jpg$', fn, re.IGNORECASE)]
filelist.sort(key=lambda var:[int(x) if x.isdigit() else
x for x in re.findall(r'[^0-9]|[0-9]+', var)])
for f in filelist:
fbname = os.path.splitext(os.path.basename(f))[0]
for e,cls in enumerate(pts_cls): # for each (img_id, clst_id) pair
if str(cls[0])==fbname: # check if image_id corresponds to file basename on disk)
if cls[1]==-1: # if cluster_id is -1 (->noise)
outdir = srcdir+'cluster_'+'Noise'+'/'
else:
outdir = srcdir+'cluster_'+str(cls[1])+'/'
if not os.path.isdir(outdir):
os.makedirs(outdir)
dstf = outdir+os.path.basename(f)
if os.path.isfile(dstf)==False:
shutil.copy2(f,dstf)
当然,由于我对Python还很陌生,所以欢迎任何其他解释良好的改进 我觉得你把这件事复杂化了很多。由于您的图像名称是唯一的(只能有一个
image\u id
),因此您可以安全地将pts\u cls
转换为dict
,并在现场进行快速查找,而不是每次都在成对列表中循环。您还可以在不需要的地方使用regex,并且打包路径只是为了以后解包
此外,如果源目录中的图像不在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
如果您确定
src_dir
中的*.jpg文件的名称中没有非整数,则可以将文件名转换为整数,以在文件列表生成中开始-只需将fn[:-4]
替换为int(fn[:-4])
。但我不建议您这样做,因为您永远不知道您的文件可能是如何命名的。似乎没有进入if循环:if name in cluster\u map:
@s.k.-在生成cluster\u map
字典后,您能否打印:打印(cluster\u map.items()[0])
?是的,结果是:(1,-s.k./code>如果我添加打印(名称)
就在for循环的顶部,我得到了图像ID。如果我在If语句的顶部添加print(name)
就没有任何回报。
cluster_map = {str(k): v for k, v in pts_cls}