我的目录中有大约一百万个文件,而且它们的数量可能还会增加. 对于机器学习,我想从这些文件中随机抽样,而不进行替换.我怎么才能快速完成这项工作呢?Os.listdir(路径)对我来说太慢了.

推荐答案

我的目录里有大约一百万个文件...Os.listdir(路径)对我来说太慢了.

这是你的问题的核心,我通常听说一种被称为bucketing个你的文件的技术来解决它,尽管网络搜索似乎没有什么特别的帮助.

需要存储大量没有任何特定 struct 的文件的程序通常使用Bakting,例如,MediaWiki实例(运行Wikipedia的软件)中的所有媒体文件(如图像).以下是维基百科上的Stack Overflow徽标:

https://upload.wikimedia.org/wikipedia/commons/0/02/Stack_Overflow_logo.svg

看到URL中的0/02了吗?这就是水桶.根据某种算法,维基百科中的所有文件都将是hashed--例如sha256,尽管不一定是这样--02将是该散列的前两个十六进制数字.(斜杠前的0只是02的第一个数字;在本例中,它被用作第二级扣环.)

如果MediaWiki只是将每个文件存储在一个庞大的目录中,那么访问该目录中的文件将非常慢,因为尽管OS文件夹可以存储任意多个文件,但它们的设计容量不能超过几千个.通过hashing个文件的内容,你会得到一个看起来像是该文件唯一的随机十六进制数字的字符串,如果你把所有以相同的前两个十六进制数字开头的文件(比如02放在一个名为02的文件夹中),你会得到256个文件夹(前两个十六进制数字的每个可能值一个),关键是each of those 256 folders contains a roughly equal number of files.

当你试图查找特定的文件时,就像MediaWiki一样,如果你以这种方式存储文件,你显然需要知道哈希值才能找到文件.但在您的情况下,您只想加载random个文件.这样也可以:

  • 散列所有文件并存储它们(可能有其他级别,例如,您可能需要像12/34/filename.ext这样的文件,这样您就有65,536个存储桶).您可以使用hashlib之类的东西或sha256sum之类的命令行工具来获取文件散列.您不需要重命名文件,只要根据其散列的前几个十六进制数字将它们分组到目录中即可.
  • 现在,每次您想要随机文件时, Select 一个随机存储桶(如果您使用其他级别,还可能 Select 随机子存储桶),然后在该存储桶中 Select 一个随机文件.

这样做比在包含一百万个文件的目录上使用listdir,然后在这些文件中随机 Select 要快得多.


注意:我在这里仅以MediaWiki为例,因为我熟悉它的一些内部 struct ;许多软件产品都做类似的事情.

Python相关问答推荐

回归回溯-2D数组中的单词搜索

如何使用scikit-learn Python库中的Agglomerative集群算法以及集群中声明的对象数量?

将numpy数组与空数组相加

了解shuffle在NP.random.Generator.choice()中的作用

当值是一个integer时,在Python中使用JMESPath来验证字典中的值(例如:1)

ambda将时间戳与组内另一列的所有时间戳进行比较

使文本输入中的文本与标签中的文本相同

数字梯度的意外值

如何根据条件在多指标框架上进行groupby

具有多个选项的计数_匹配

点到面的Y距离

运行Python脚本时,用作命令行参数的SON文本

从numpy数组和参数创建收件箱

发生异常:TclMessage命令名称无效.!listbox"

给定高度约束的旋转角解析求解

如何禁用FastAPI应用程序的Swagger UI autodoc中的application/json?

python panda ExcelWriter切换动态公式到数组公式

如何使用OpenGL使球体遵循Python中的八样路径?

巨 Python :逆向猜谜游戏

如何根据rame中的列值分别分组值