鱼C论坛

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

数据集划分

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

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

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

x
求助一个代码,能够将指定文件夹内的子文件夹中的所有csv文件移动出来20%作为测试集,移动出来的csv文件放在目标路径的与源路径相同的子文件夹内,作为测试集的目标路径的每个子文件夹内至少两个csv文件
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

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

让我们来看看具体的代码实现:

  1. import os
  2. import shutil
  3. import random
  4. from collections import defaultdict

  5. def move_csv_files(source_dir, target_dir):
  6.     # 获取所有csv文件的路径
  7.     csv_files = []
  8.     for root, dirs, files in os.walk(source_dir):
  9.         for file in files:
  10.             if file.endswith(".csv"):
  11.                 csv_files.append(os.path.join(root, file))
  12.    
  13.     # 确定测试集的大小,这里假设是20%
  14.     num_test_files = int(0.2 * len(csv_files))
  15.    
  16.     # 随机选择测试集文件
  17.     test_files = random.sample(csv_files, num_test_files)
  18.    
  19.     # 按照源文件夹结构,将测试集文件移动到目标路径下的相应子文件夹
  20.     for file in test_files:
  21.         rel_path = os.path.relpath(file, source_dir)
  22.         target_path = os.path.join(target_dir, rel_path)
  23.         target_folder = os.path.dirname(target_path)
  24.         
  25.         # 确保目标文件夹存在,如果不存在则创建
  26.         if not os.path.exists(target_folder):
  27.             os.makedirs(target_folder)
  28.         
  29.         # 移动文件
  30.         shutil.move(file, target_path)
  31.    
  32.     # 确保每个子文件夹至少有两个测试集文件
  33.     test_files_dict = defaultdict(list)
  34.     for file in test_files:
  35.         rel_path = os.path.relpath(file, source_dir)
  36.         folder = os.path.dirname(rel_path)
  37.         test_files_dict[folder].append(file)
  38.    
  39.     for folder, files in test_files_dict.items():
  40.         if len(files) < 2:
  41.             # 找到另一个文件移动到该文件夹
  42.             for file in csv_files:
  43.                 rel_path = os.path.relpath(file, source_dir)
  44.                 if os.path.dirname(rel_path) == folder and file not in files:
  45.                     target_path = os.path.join(target_dir, rel_path)
  46.                     shutil.move(file, target_path)
  47.                     files.append(file)
  48.                     break

  49. # 示例用法:
  50. source_directory = '/path/to/source_directory'
  51. target_directory = '/path/to/target_directory'

  52. move_csv_files(source_directory, target_directory)
复制代码


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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

这个不对啊  没有输出东西,目标路径没有文件
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

  1. import os
  2. import shutil
  3. import random
  4. from collections import defaultdict

  5. def move_csv_files(source_dir, target_dir):
  6.     # 获取所有csv文件的路径
  7.     csv_files = []
  8.     for root, dirs, files in os.walk(source_dir):
  9.         for file in files:
  10.             if file.endswith(".csv"):
  11.                 csv_files.append(os.path.join(root, file))
  12.    
  13.     # 确定测试集的大小,这里假设是20%
  14.     num_test_files = max(2, int(0.2 * len(csv_files)))
  15.    
  16.     # 随机选择测试集文件
  17.     test_files = random.sample(csv_files, num_test_files)
  18.    
  19.     # 按照源文件夹结构,将测试集文件移动到目标路径下的相应子文件夹
  20.     for file in test_files:
  21.         rel_path = os.path.relpath(file, source_dir)
  22.         target_path = os.path.join(target_dir, rel_path)
  23.         target_folder = os.path.dirname(target_path)
  24.         
  25.         # 确保目标文件夹存在,如果不存在则创建
  26.         if not os.path.exists(target_folder):
  27.             os.makedirs(target_folder)
  28.             print(f"Created directory: {target_folder}")
  29.         
  30.         # 移动文件
  31.         shutil.move(file, target_path)
  32.         print(f"Moved file {file} to {target_path}")
  33.    
  34.     # 确保每个子文件夹至少有两个测试集文件
  35.     test_files_dict = defaultdict(list)
  36.     for file in test_files:
  37.         rel_path = os.path.relpath(file, source_dir)
  38.         folder = os.path.dirname(rel_path)
  39.         test_files_dict[folder].append(file)
  40.    
  41.     for folder, files in test_files_dict.items():
  42.         if len(files) < 2:
  43.             print(f"Folder {folder} has less than 2 test files. Adding more files...")
  44.             additional_files = [file for file in csv_files if os.path.dirname(os.path.relpath(file, source_dir)) == folder and file not in files]
  45.             while len(files) < 2 and additional_files:
  46.                 additional_file = additional_files.pop(0)
  47.                 rel_path = os.path.relpath(additional_file, source_dir)
  48.                 target_path = os.path.join(target_dir, rel_path)
  49.                 shutil.move(additional_file, target_path)
  50.                 files.append(additional_file)
  51.                 print(f"Moved file {additional_file} to {target_path}")

  52. # 示例用法:
  53. source_directory = '/path/to/source_directory'
  54. target_directory = '/path/to/target_directory'

  55. move_csv_files(source_directory, target_directory)
复制代码


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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://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
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

以下是修改后的代码:

  1. import os
  2. import shutil
  3. import random
  4. from collections import defaultdict

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

  22.     # 随机选择测试集文件
  23.     test_files = random.sample(csv_files, num_test_files)
  24.    
  25.     # 按照源文件夹结构,将测试集文件移动到目标路径下的相应子文件夹
  26.     for file in test_files:
  27.         rel_path = os.path.relpath(file, source_dir)
  28.         target_path = os.path.join(target_dir, rel_path)
  29.         target_folder = os.path.dirname(target_path)
  30.         
  31.         # 确保目标文件夹存在,如果不存在则创建
  32.         if not os.path.exists(target_folder):
  33.             os.makedirs(target_folder)
  34.             print(f"Created directory: {target_folder}")
  35.         
  36.         # 移动文件
  37.         shutil.move(file, target_path)
  38.         print(f"Moved file {file} to {target_path}")
  39.    
  40.     # 确保每个子文件夹至少有两个测试集文件
  41.     test_files_dict = defaultdict(list)
  42.     for file in test_files:
  43.         rel_path = os.path.relpath(file, source_dir)
  44.         folder = os.path.dirname(rel_path)
  45.         test_files_dict[folder].append(file)
  46.    
  47.     for folder, files in test_files_dict.items():
  48.         if len(files) < 2:
  49.             print(f"Folder {folder} has less than 2 test files. Adding more files...")
  50.             additional_files = [file for file in csv_files if os.path.dirname(os.path.relpath(file, source_dir)) == folder and file not in files]
  51.             while len(files) < 2 and additional_files:
  52.                 additional_file = additional_files.pop(0)
  53.                 rel_path = os.path.relpath(additional_file, source_dir)
  54.                 target_path = os.path.join(target_dir, rel_path)
  55.                 shutil.move(additional_file, target_path)
  56.                 files.append(additional_file)
  57.                 print(f"Moved file {additional_file} to {target_path}")

  58. # 示例用法:
  59. source_directory = '/path/to/source_directory'
  60. target_directory = '/path/to/target_directory'

  61. move_csv_files(source_directory, target_directory)
复制代码


主要改进点:

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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://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文件移动
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

def mov ...


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

  1. import os
  2. import shutil
  3. import random

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

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

  15.         test_files = random.sample(csv_files, num_test_files)
  16.         
  17.         for file in test_files:
  18.             src_file = os.path.join(root, file)
  19.             rel_path = os.path.relpath(root, src_folder)
  20.             dst_subfolder = os.path.join(dst_folder, rel_path)
  21.             if not os.path.exists(dst_subfolder):
  22.                 os.makedirs(dst_subfolder)
  23.             dst_file = os.path.join(dst_subfolder, file)
  24.             shutil.move(src_file, dst_file)
  25.             print(f'Moved {src_file} to {dst_file}')

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

  28. move_csv_files(src_folder, dst_folder)
复制代码


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

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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-23 02:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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