2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonでファイルをランダムサンプリングしたい

Last updated at Posted at 2020-05-02

やること

  1. ファイルを100個つくる
  2. 指定した拡張子のファイルパスを取得
  3. ランダムに10個選び、別ディレクトリにコピー

ディレクトリ構成

.
├── input
│   └── _sampled
└── src
    └── random_sampling.py

コード

※ 全て標準ライブラリなのでインストール不要

random_smpling.py
from pprint import pprint
import os
from pathlib import Path
import random
import shutil


class FileControler(object):
    def make_file(self, output_dir, file_name, content='') -> None:
        """ ファイル作成 """
        # 出力先ディレクトリがなければ作成
        os.makedirs(output_dir, exist_ok=True)
        # 出力先ディレクトリとファイル名を結合
        file_path = os.path.join(output_dir, file_name)
        # ファイル作成
        with open(file_path, mode='w') as f:
            # 初期値では空ファイル 作成
            f.write(content)

    def get_files_path(self, input_dir, pattern):
        """ ファイルパスの取得 """
        # ディレクトリを指定しパスオブジェクトを生成
        path_obj = Path(input_dir)
        # glob形式でファイルをマッチ
        files_path = path_obj.glob(pattern)
        # 文字列として扱うためposix変換
        files_path_posix = [file_path.as_posix() for file_path in files_path]
        return files_path_posix

    def random_sampling(self, files_path, sampl_num, output_dir, fix_seed=True) -> None:
        """ ランダムサンプリング """
        # 毎回同じファイルをサンプリングする場合はシード値を固定する
        if fix_seed is True:
            random.seed(0)
        # ファイル群のパスとサンプル数を指定
        files_path_sampled = random.sample(files_path, sampl_num)
        # 出力先ディレクトリがなければ作成
        os.makedirs(output_dir, exist_ok=True)
        # コピー
        for file_path in files_path_sampled:
            shutil.copy(file_path, output_dir)

実行

インスタンス作成

file_controler = FileControler()

ディレクトリ

input/の中にファイルを100個つくる
input/_sampledの中へサンプリングしたファイルをコピー

all_files_dir = '../input'
sampled_dir = '../input/_sampled'

まずは100ファイル作る

.py, .txtのファイルをそれぞれ50個づつ

for i in range(1, 51):
    file_controler.make_file(all_files_dir, f'file{i}.py')
    file_controler.make_file(all_files_dir, f'file{i}.txt')

.pyファイルのパスだけ取得

from pprint import pprint


pattern = '*.py'
files_path = file_controler.get_files_path(all_files_dir, pattern)

pprint(files_path)
# ['../input/file8.py',
#  '../input/file28.py',
#  '../input/file38.py',
#  ...
#  '../input/file25.py',
#  '../input/file35.py',
#  '../input/file50.py']
#

print(len(files_path))
# 50

10ファイル分ランダムサンプリング

sample_num = 10
file_controler.random_sampling(files_path, sample_num, sampled_dir)

確認

ターミナル
ls input/_sampled

file10.py file23.py file3.py  file35.py file36.py file37.py file38.py file4.py  file41.py file43.py
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?