如何使用Python按70%/15%/15%的比例将文件移动至不同目录?
Split and Move Image Files by Proportion in Python
Got it, let's work through this problem together. You need to split your image files into three groups (70%, 15%, 15%) and move each group to a separate target folder. The key here is to randomize the file list first (so your splits aren't biased by the original file order) and then calculate the exact number of files for each group.
Here's a complete, working solution:
import shutil import os import random # Set your paths here source_dir = '/path/to/source_folder' train_dir = '/path/to/train_folder' # 70% of files val_dir = '/path/to/validation_folder' # 15% of files test_dir = '/path/to/test_folder' # Remaining 15% of files # Create target directories if they don't exist for dir_path in [train_dir, val_dir, test_dir]: if not os.path.exists(dir_path): os.makedirs(dir_path) # Get all image files from source directory file_names = os.listdir(source_dir) # Optional: Filter to only include image files (in case there are non-image files) file_names = [f for f in file_names if f.lower().endswith(('.jpeg', '.jpg', '.png', '.gif'))] # Randomize the file list to ensure even distribution random.shuffle(file_names) total_files = len(file_names) # Calculate the number of files for each group train_count = int(total_files * 0.7) val_count = int(total_files * 0.15) # Test count takes whatever is left to avoid rounding errors test_count = total_files - train_count - val_count # Split the file list into three groups train_files = file_names[:train_count] val_files = file_names[train_count:train_count + val_count] test_files = file_names[train_count + val_count:] # Move files to their respective directories def move_files(file_list, target_dir): for file_name in file_list: source_path = os.path.join(source_dir, file_name) target_path = os.path.join(target_dir, file_name) shutil.move(source_path, target_path) move_files(train_files, train_dir) move_files(val_files, val_dir) move_files(test_files, test_dir) print(f"Moved {train_count} files to {train_dir}") print(f"Moved {val_count} files to {val_dir}") print(f"Moved {test_count} files to {test_dir}")
Key Details to Note:
- Randomization: Using
random.shuffle()ensures that your file splits are not skewed by the original order of files (e.g., if all files from one category are grouped together in the source list). - Directory Creation: The code checks if target folders exist and creates them if they don't—this prevents
shutil.move()from throwing errors. - File Filtering: The optional list comprehension filters for common image extensions, which is useful if your source folder has any non-image files.
- Avoiding Rounding Errors: Instead of calculating
test_countas0.15 * total_files, we subtract the other two counts from the total. This ensures all files are accounted for, even if the total number of files doesn't divide perfectly by the percentages.
If you want to make the splits reproducible (so you get the same grouping every time you run the code), you can add a seed to the random module:
random.seed(42) # Use any integer as the seed random.shuffle(file_names)
内容的提问来源于stack exchange,提问作者Yogesh Riyat
相关产品推荐
相关产品推荐

