如何从 Python 中的文件系统中随机抽样文件
How to randomly sample files from a filesystem in Python
是否有一种高效的方法可以从文件系统中对文件进行采样,直到您达到 Python 中的目标样本大小?
例如,假设我在任意嵌套的文件夹结构中有 1000 万个文件,我想要一个包含 20,000 个文件的样本。
目前,对于 ~100k 左右的小型平面目录,我可以这样做:
import os
import random
sample_size = 20_000
sample = random.sample(list(os.scandir(path)), sample_size)
for direntry in sample:
print(direntry.path)
但是,这并不能很好地扩展。所以,我想也许可以将随机检查放入循环中。这种方法可行,但有一个问题,如果目录中的文件数量接近 sample_size
,它可能无法获取完整目标 sample_size
,我需要跟踪哪些文件被包含在样本中然后继续循环直到我填满样本桶。
import os
import random
sample_size = 20_000
count = 0
for direntry in os.scandir(path):
if random.randint(0, 10) < 5:
continue
print(direntry.path)
count += 1
if count >= sample_size:
print("reached sample_size")
break
关于如何从大型目录结构中随机抽取大量文件的任何想法?
使用iterators/generators 这样您就不会将所有文件都保存在内存中。并使用 Reservoir sampling 从基本的文件名流中挑选选定的样本。
代码
from pathlib import Path
import random
pathlist = Path("C:/Users/XXX/Documents").glob('**/*.py')
nof_samples = 10
rc = []
for k, path in enumerate(pathlist):
if k < nof_samples:
rc.append(str(path)) # because path is object not string
else:
i = random.randint(0, k)
if i < nof_samples:
rc[i] = str(path)
print(len(rc))
print(rc)
是否有一种高效的方法可以从文件系统中对文件进行采样,直到您达到 Python 中的目标样本大小?
例如,假设我在任意嵌套的文件夹结构中有 1000 万个文件,我想要一个包含 20,000 个文件的样本。
目前,对于 ~100k 左右的小型平面目录,我可以这样做:
import os
import random
sample_size = 20_000
sample = random.sample(list(os.scandir(path)), sample_size)
for direntry in sample:
print(direntry.path)
但是,这并不能很好地扩展。所以,我想也许可以将随机检查放入循环中。这种方法可行,但有一个问题,如果目录中的文件数量接近 sample_size
,它可能无法获取完整目标 sample_size
,我需要跟踪哪些文件被包含在样本中然后继续循环直到我填满样本桶。
import os
import random
sample_size = 20_000
count = 0
for direntry in os.scandir(path):
if random.randint(0, 10) < 5:
continue
print(direntry.path)
count += 1
if count >= sample_size:
print("reached sample_size")
break
关于如何从大型目录结构中随机抽取大量文件的任何想法?
使用iterators/generators 这样您就不会将所有文件都保存在内存中。并使用 Reservoir sampling 从基本的文件名流中挑选选定的样本。
代码
from pathlib import Path
import random
pathlist = Path("C:/Users/XXX/Documents").glob('**/*.py')
nof_samples = 10
rc = []
for k, path in enumerate(pathlist):
if k < nof_samples:
rc.append(str(path)) # because path is object not string
else:
i = random.randint(0, k)
if i < nof_samples:
rc[i] = str(path)
print(len(rc))
print(rc)