从文件夹中随机抽取文件进行抽样

6
我需要一种从文件夹中随机拉取10%文件进行抽样的方法,幸运的是,我的当前文件按数字顺序编号。因此,我目前的方法是列出文件名,解析数字部分,提取最大值和最小值,计算文件数量并乘以0.1,然后使用random.sample来获取“随机[10%]样本”。我还将这些名称写入.txt文件,然后使用shutil.copy来移动实际文件。
显然,如果我有离群值,即在其他文件中有一个文件345.txt,而它的编号从513.txt - 678.txt。我想知道是否有一种直接从文件夹中随机选择文件的方法?我已经查找过了,没有找到更好的方法。
谢谢。

1
忽略文件名中的编号...只需加载所有文件的列表,然后使用随机索引进入列表。 - Grantly
1
@Grantly 或者直接从列表中随机选取值,而不必担心索引。 - abarnert
5个回答

11

使用numpy.random.choice(array, N),你可以从数组中随机选择N个元素。

import numpy as np
import os

# list all files in dir
files = [f for f in os.listdir('.') if os.path.isfile(f)]

# select 0.1 of the files randomly 
random_files = np.random.choice(files, int(len(files)*.1))

2

我尝试了其他方法,但很难让它们与我的代码配合使用,所以我想出了这个方法。

output_folder = 'C:/path/to/folder'
for x in range(int(len(files) *.1)):
    to_copy = choice(files)
    shutil.copy(os.path.join(subdir, to_copy), output_folder)            

1
这将为您提供文件夹中名称列表,其中mypath是文件夹的路径。
from os import listdir
from os.path import isfile, join
from random import shuffle
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
shuffled = shuffle(onlyfiles)
small_list = shuffled[:len(shuffled)/10]

这应该可以工作。

将整个列表就地洗牌的效率比仅在需要10%的值时从中抽样要低,但这很简单和明显易懂,除非性能很重要,否则它很容易获胜。我怀疑性能成本甚至在整个应用程序中也无法衡量。 - abarnert
如果性能是一个问题,那么在每个文件上调用isfile可能会有影响;值得考虑从listdir切换到scandir以避免所有这些stat调用。 - abarnert

0
你可以使用以下策略:
  1. 使用 list = os.listdir(path) 获取目录中所有文件的路径列表。
  2. 接下来,使用 range = len(list) 函数计算文件数量。
  3. 使用 range 数字,您可以获取随机项数字,例如 random_position = random.randrange(1, range)
  4. 重复步骤3并将值保存在列表中,直到获得足够的位置(在您的情况下为范围/10)
  5. 之后,您可以像这样获取所需的文件名 list[random_position]
使用循环 for 进行迭代。
希望这能帮到你!

0

基于Karl的解决方案(在Win 10,Python 3.x下对我无效),我想出了这个:

import numpy as np
import os

# List all files in dir
files = os.listdir("C:/Users/.../Myfiles")

# Select 0.5 of the files randomly 
random_files = np.random.choice(files, int(len(files)*.5))

# Get the remaining files
other_files = [x for x in files if x not in random_files]

# Do something with the files
for x in random_files:
    print(x)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接