You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python新手求助:按图片文件名后缀分类至新文件夹及报错解决

解决AttributeError: 'numpy.ndarray' object has no attribute 'endswith'问题

首先咱们得先揪出报错的根源:你当前代码里的all_images列表存的是用cv2.imread读取后的numpy像素数组,而不是图片的文件名字符串。endswith()是字符串专属的方法,自然没法用在numpy数组上,这就是报错的原因啦。

结合你的需求——根据文件名结尾把三个文件夹里的图片分类到新文件夹,其实完全不需要先把图片加载到内存里,直接操作文件(复制/移动)更高效,还能彻底避开这个错误。

修正后的完整代码

import os
from shutil import copyfile

# 定义要处理的源文件夹列表
source_folders = [
    'C:/Users/shiva/OneDrive/Desktop/WORK/Bildverarbeitung_Reaktion/Pictures/I3te_Reaktion',
    'C:/Users/shiva/OneDrive/Desktop/WORK/Bildverarbeitung_Reaktion/Pictures/4te_Reaktion',
    'C:/Users/shiva/OneDrive/Desktop/WORK/Bildverarbeitung_Reaktion/Pictures/5te_Reaktion',
]

# 自定义分类规则:键是目标文件夹名,值是要匹配的文件名标识(支持多个)
category_rules = {
    '1550_R_images': ['1550_R_', '.jpeg', '.jpg'],  # 匹配含1550_R_的jpeg/jpg文件
    '1500_images': ['1500_'],  # 匹配含1500_的文件
    'unclassified_images': []  # 兜底文件夹,放不匹配规则的文件
}

# 自动创建所有目标文件夹(不存在则创建,已存在不会报错)
base_output_dir = 'C:/Users/shiva/OneDrive/Desktop/WORK/Bildverarbeitung_Reaktion/Classified_Images'
for category in category_rules.keys():
    target_dir = os.path.join(base_output_dir, category)
    os.makedirs(target_dir, exist_ok=True)

# 遍历每个源文件夹,处理文件
for folder in source_folders:
    for filename in os.listdir(folder):
        file_full_path = os.path.join(folder, filename)
        # 跳过子文件夹,只处理文件
        if not os.path.isfile(file_full_path):
            continue
        
        # 检查文件是否匹配分类规则
        matched = False
        for category, markers in category_rules.items():
            if not markers:  # 跳过兜底规则,最后统一处理
                continue
            # 判断文件名是否包含任一指定标识
            if any(filename.endswith(marker) or marker in filename for marker in markers):
                target_path = os.path.join(base_output_dir, category, filename)
                copyfile(file_full_path, target_path)
                matched = True
                break
        # 没匹配到任何规则的文件,放入兜底文件夹
        if not matched:
            target_path = os.path.join(base_output_dir, 'unclassified_images', filename)
            copyfile(file_full_path, target_path)

print("图片分类完成!")

关键改动说明

  • 放弃不必要的图片加载:直接操作文件路径和文件名,既避免了numpy数组的类型错误,又节省内存资源。
  • 全程保留文件名信息:所有判断操作都针对字符串类型的文件名,endswith()方法就能正常工作了。
  • 灵活的分类规则:用字典定义分类逻辑,后续你想新增分类、调整匹配标识,直接修改字典就行,非常方便。
  • 自动创建目标文件夹:用os.makedirs(..., exist_ok=True)确保目标文件夹存在,不用手动提前创建。
  • 兜底处理机制:新增了unclassified_images文件夹,防止有不符合规则的文件被遗漏。

如果你确实需要加载图片再保存(比如要做预处理)

要是你的需求是先加载图片做处理,再按文件名分类保存,那得修改加载函数,同时保存文件名和图片数据:

import cv2
import os

def load_images_with_filenames(folder):
    image_info_list = []
    for filename in os.listdir(folder):
        img_path = os.path.join(folder, filename)
        img = cv2.imread(img_path)
        if img is not None:
            # 保存(文件名, 图片数组, 原文件路径)
            image_info_list.append( (filename, img, img_path) )
    return image_info_list

# 源文件夹列表
source_folders = [
    'C:/Users/shiva/OneDrive/Desktop/WORK/Bildverarbeitung_Reaktion/Pictures/I3te_Reaktion',
    'C:/Users/shiva/OneDrive/Desktop/WORK/Bildverarbeitung_Reaktion/Pictures/4te_Reaktion',
    'C:/Users/shiva/OneDrive/Desktop/WORK/Bildverarbeitung_Reaktion/Pictures/5te_Reaktion',
]

# 加载所有带文件名的图片数据
all_image_info = []
for folder in source_folders:
    all_image_info.extend(load_images_with_filenames(folder))

# 创建输出文件夹
output_dir = 'C:/Users/shiva/OneDrive/Desktop/WORK/Bildverarbeitung_Reaktion/Classified_Images'
os.makedirs(output_dir, exist_ok=True)

# 按文件名规则分类保存
for filename, img, _ in all_image_info:
    if any(filename.endswith(x) for x in ['1550_R_1.jpeg', '1550_N', '.jpeg','.jpg']):
        target_save_path = os.path.join(output_dir, filename)
        cv2.imwrite(target_save_path, img)

这样就能正确调用filename.endswith()了,因为filename是实打实的字符串类型。

内容的提问来源于stack exchange,提问作者SHIVANI DEEPAK CHOUDHARY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 17:57:32