鱼C论坛

 找回密码
 立即注册
查看: 239|回复: 7

数据集划分

[复制链接]
发表于 2024-6-20 11:10:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
求助一个代码,能够将指定文件夹内的子文件夹中的所有csv文件移动出来20%作为测试集,移动出来的csv文件放在目标路径的与源路径相同的子文件夹内,作为测试集的目标路径的每个子文件夹内至少两个csv文件
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-6-20 11:11:18 | 显示全部楼层
哦哟,这个问题正好能让我展示我的代码功底!我们来一步步解决:

首先,你需要一个能够处理文件操作的Python库,比如`os`和`shutil`。然后,我们可以按照如下步骤进行:

1. **获取所有csv文件路径**:遍历指定文件夹及其子文件夹,找到所有的csv文件路径。
2. **划分数据集**:将找到的csv文件按照20%的比例移动到测试集目标路径。
3. **确保每个子文件夹有至少两个测试集文件**:遍历移动后的文件,确保每个子文件夹内的测试集文件至少有两个。

让我们来看看具体的代码实现:
import os
import shutil
import random
from collections import defaultdict

def move_csv_files(source_dir, target_dir):
    # 获取所有csv文件的路径
    csv_files = []
    for root, dirs, files in os.walk(source_dir):
        for file in files:
            if file.endswith(".csv"):
                csv_files.append(os.path.join(root, file))
    
    # 确定测试集的大小,这里假设是20%
    num_test_files = int(0.2 * len(csv_files))
    
    # 随机选择测试集文件
    test_files = random.sample(csv_files, num_test_files)
    
    # 按照源文件夹结构,将测试集文件移动到目标路径下的相应子文件夹
    for file in test_files:
        rel_path = os.path.relpath(file, source_dir)
        target_path = os.path.join(target_dir, rel_path)
        target_folder = os.path.dirname(target_path)
        
        # 确保目标文件夹存在,如果不存在则创建
        if not os.path.exists(target_folder):
            os.makedirs(target_folder)
        
        # 移动文件
        shutil.move(file, target_path)
    
    # 确保每个子文件夹至少有两个测试集文件
    test_files_dict = defaultdict(list)
    for file in test_files:
        rel_path = os.path.relpath(file, source_dir)
        folder = os.path.dirname(rel_path)
        test_files_dict[folder].append(file)
    
    for folder, files in test_files_dict.items():
        if len(files) < 2:
            # 找到另一个文件移动到该文件夹
            for file in csv_files:
                rel_path = os.path.relpath(file, source_dir)
                if os.path.dirname(rel_path) == folder and file not in files:
                    target_path = os.path.join(target_dir, rel_path)
                    shutil.move(file, target_path)
                    files.append(file)
                    break

# 示例用法:
source_directory = '/path/to/source_directory'
target_directory = '/path/to/target_directory'

move_csv_files(source_directory, target_directory)

这段代码做了以下几件事情:
- 遍历指定的源文件夹及其子文件夹,找到所有的csv文件。
- 随机选择20%的csv文件作为测试集,并按照源文件夹的结构将其移动到目标路径下的相应子文件夹。
- 确保每个子文件夹内的测试集文件至少有两个,如果不足则从其余的csv文件中选取适当数量的文件移动到相应子文件夹。

记得把`source_directory`和`target_directory`替换成你实际的源路径和目标路径!希望这个解决方案对你有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-6-20 11:22:12 | 显示全部楼层
FishC 发表于 2024-6-20 11:11
哦哟,这个问题正好能让我展示我的代码功底!我们来一步步解决:

首先,你需要一个能够处理文件操作的Py ...

这个不对啊  没有输出东西,目标路径没有文件
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-6-20 11:22:42 | 显示全部楼层
1207139945 发表于 2024-06-20 11:22
这个不对啊  没有输出东西,目标路径没有文件


好的,看来需要对代码进行一些修正和增强。我们确保输出一些日志信息,以便调试。同时确保目标路径内文件夹的创建和文件移动逻辑正确。以下是改进后的代码:
import os
import shutil
import random
from collections import defaultdict

def move_csv_files(source_dir, target_dir):
    # 获取所有csv文件的路径
    csv_files = []
    for root, dirs, files in os.walk(source_dir):
        for file in files:
            if file.endswith(".csv"):
                csv_files.append(os.path.join(root, file))
    
    # 确定测试集的大小,这里假设是20%
    num_test_files = max(2, int(0.2 * len(csv_files)))
    
    # 随机选择测试集文件
    test_files = random.sample(csv_files, num_test_files)
    
    # 按照源文件夹结构,将测试集文件移动到目标路径下的相应子文件夹
    for file in test_files:
        rel_path = os.path.relpath(file, source_dir)
        target_path = os.path.join(target_dir, rel_path)
        target_folder = os.path.dirname(target_path)
        
        # 确保目标文件夹存在,如果不存在则创建
        if not os.path.exists(target_folder):
            os.makedirs(target_folder)
            print(f"Created directory: {target_folder}")
        
        # 移动文件
        shutil.move(file, target_path)
        print(f"Moved file {file} to {target_path}")
    
    # 确保每个子文件夹至少有两个测试集文件
    test_files_dict = defaultdict(list)
    for file in test_files:
        rel_path = os.path.relpath(file, source_dir)
        folder = os.path.dirname(rel_path)
        test_files_dict[folder].append(file)
    
    for folder, files in test_files_dict.items():
        if len(files) < 2:
            print(f"Folder {folder} has less than 2 test files. Adding more files...")
            additional_files = [file for file in csv_files if os.path.dirname(os.path.relpath(file, source_dir)) == folder and file not in files]
            while len(files) < 2 and additional_files:
                additional_file = additional_files.pop(0)
                rel_path = os.path.relpath(additional_file, source_dir)
                target_path = os.path.join(target_dir, rel_path)
                shutil.move(additional_file, target_path)
                files.append(additional_file)
                print(f"Moved file {additional_file} to {target_path}")

# 示例用法:
source_directory = '/path/to/source_directory'
target_directory = '/path/to/target_directory'

move_csv_files(source_directory, target_directory)

代码增强了以下几点:
1. 添加了日志输出,方便调试每一步操作。
2. 确保目标路径中每个子文件夹至少有两个测试集文件,如果不足则从其余的csv文件中选取适当数量的文件移动到相应子文件夹。
3. 使用`max(2, int(0.2 * len(csv_files)))`确保至少选择2个文件作为测试集,防止文件过少时无法满足每个子文件夹至少两个文件的要求。

请再次尝试运行这个代码,并确保源路径和目标路径的正确设置。如果还有问题,请告诉我!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-6-20 11:55:56 | 显示全部楼层
FishC 发表于 2024-6-20 11:22
好的,看来需要对代码进行一些修正和增强。我们确保输出一些日志信息,以便调试。同时确保目标路径内文 ...

出现错误Traceback (most recent call last):
  File "/home/data/pxy/apython/a代码/ECAPA-TDNN-main/tool/datacreate.py", line 62, in <module>
    move_csv_files(source_directory, target_directory)
  File "/home/data/pxy/apython/a代码/ECAPA-TDNN-main/tool/datacreate.py", line 19, in move_csv_files
    test_files = random.sample(csv_files, num_test_files)
  File "/home/data/anaconda3/envs/loss/lib/python3.8/random.py", line 363, in sample
    raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-6-20 11:56:20 | 显示全部楼层
1207139945 发表于 2024-06-20 11:55
出现错误Traceback (most recent call last):
  File ...


好的,出现这个错误是因为要选择的测试集文件数量大于现有的csv文件数量或者数量是负值。我们需要在代码中添加检查来避免这种情况发生。

以下是修改后的代码:
import os
import shutil
import random
from collections import defaultdict

def move_csv_files(source_dir, target_dir):
    # 获取所有csv文件的路径
    csv_files = []
    for root, dirs, files in os.walk(source_dir):
        for file in files:
            if file.endswith(".csv"):
                csv_files.append(os.path.join(root, file))
    
    # 确保有足够的文件进行划分
    if len(csv_files) < 2:
        print("Not enough CSV files to create a test set.")
        return
    
    # 确定测试集的大小,这里假设是20%
    num_test_files = max(2, int(0.2 * len(csv_files)))
    if num_test_files > len(csv_files):
        num_test_files = len(csv_files)

    # 随机选择测试集文件
    test_files = random.sample(csv_files, num_test_files)
    
    # 按照源文件夹结构,将测试集文件移动到目标路径下的相应子文件夹
    for file in test_files:
        rel_path = os.path.relpath(file, source_dir)
        target_path = os.path.join(target_dir, rel_path)
        target_folder = os.path.dirname(target_path)
        
        # 确保目标文件夹存在,如果不存在则创建
        if not os.path.exists(target_folder):
            os.makedirs(target_folder)
            print(f"Created directory: {target_folder}")
        
        # 移动文件
        shutil.move(file, target_path)
        print(f"Moved file {file} to {target_path}")
    
    # 确保每个子文件夹至少有两个测试集文件
    test_files_dict = defaultdict(list)
    for file in test_files:
        rel_path = os.path.relpath(file, source_dir)
        folder = os.path.dirname(rel_path)
        test_files_dict[folder].append(file)
    
    for folder, files in test_files_dict.items():
        if len(files) < 2:
            print(f"Folder {folder} has less than 2 test files. Adding more files...")
            additional_files = [file for file in csv_files if os.path.dirname(os.path.relpath(file, source_dir)) == folder and file not in files]
            while len(files) < 2 and additional_files:
                additional_file = additional_files.pop(0)
                rel_path = os.path.relpath(additional_file, source_dir)
                target_path = os.path.join(target_dir, rel_path)
                shutil.move(additional_file, target_path)
                files.append(additional_file)
                print(f"Moved file {additional_file} to {target_path}")

# 示例用法:
source_directory = '/path/to/source_directory'
target_directory = '/path/to/target_directory'

move_csv_files(source_directory, target_directory)

主要改进点:

1. **检查文件数量**:在选择测试集文件之前,确保有足够的文件进行划分。
2. **修正num_test_files计算**:确保计算的测试集文件数量不会超过现有的csv文件数量。

请再次尝试运行这个代码,并确保源路径和目标路径设置正确。如果还有问题,请告诉我!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-6-20 12:03:27 | 显示全部楼层
FishC 发表于 2024-6-20 11:56
好的,出现这个错误是因为要选择的测试集文件数量大于现有的csv文件数量或者数量是负值。我们需要在代 ...

import os
import shutil
import random

def move_csv_files(src_folder, dst_folder, percentage):
    if not os.path.exists(dst_folder):
        os.makedirs(dst_folder)

    for root, dirs, files in os.walk(src_folder):
        for file in files:
            if file.endswith('.csv'):
                if random.random() < percentage:
                    src_file = os.path.join(root, file)
                    rel_path = os.path.relpath(root, src_folder)
                    dst_subfolder = os.path.join(dst_folder, rel_path)
                    if not os.path.exists(dst_subfolder):
                        os.makedirs(dst_subfolder)
                    dst_file = os.path.join(dst_subfolder, file)
                    shutil.move(src_file, dst_file)
                    print(f'Moved {src_file} to {dst_file}')

src_folder = '原始文件夹路径'
dst_folder = '目标文件夹路径'
percentage = 0.2

move_csv_files(src_folder, dst_folder, percentage)
直接修改一下这个代码,每次选取两个csv文件移动
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-6-20 12:03:40 | 显示全部楼层
1207139945 发表于 2024-06-20 12:03
import os
import shutil
import random

def mov ...


好的,我们在每个子文件夹中至少移动两个 CSV 文件作为测试集。如果文件数量不足,就移动所有文件。以下是改进后的代码:
import os
import shutil
import random

def move_csv_files(src_folder, dst_folder, percentage=0.2):
    if not os.path.exists(dst_folder):
        os.makedirs(dst_folder)

    for root, dirs, files in os.walk(src_folder):
        csv_files = [file for file in files if file.endswith('.csv')]
        if not csv_files:
            continue
        
        num_files = len(csv_files)
        num_test_files = max(2, int(num_files * percentage))
        num_test_files = min(num_test_files, num_files)

        test_files = random.sample(csv_files, num_test_files)
        
        for file in test_files:
            src_file = os.path.join(root, file)
            rel_path = os.path.relpath(root, src_folder)
            dst_subfolder = os.path.join(dst_folder, rel_path)
            if not os.path.exists(dst_subfolder):
                os.makedirs(dst_subfolder)
            dst_file = os.path.join(dst_subfolder, file)
            shutil.move(src_file, dst_file)
            print(f'Moved {src_file} to {dst_file}')

src_folder = '原始文件夹路径'
dst_folder = '目标文件夹路径'

move_csv_files(src_folder, dst_folder)

这个代码做了以下几个改进:

1. 确保每个子文件夹至少移动两个 CSV 文件。
2. 如果文件数量不足,则移动所有文件。
3. 添加了日志信息,便于调试。

你可以将`src_folder`和`dst_folder`替换成实际的路径,然后运行这个脚本来进行文件移动。这样就可以确保每个子文件夹内至少有两个 CSV 文件被移动到目标路径。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 00:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表