从大目录中随机延迟加载文件

问题描述 投票:0回答:1

我的目录中有大约一百万个文件,而且它们的数量可能会增长。 对于机器学习,我想从这些文件中随机采样而不进行替换。我怎样才能很快地做到这一点? os.listdir(path) 对我来说太慢了。

python random lazy-loading
1个回答
0
投票

我的目录中有大约一百万个文件... os.listdir(path) 对我来说太慢了。

这是您问题的核心,它可以通过我通常听到的一种称为“文件存储”的技术来解决,尽管对此进行网络搜索似乎并不是特别有帮助。 分桶通常由需要存储大量没有任何特定结构的文件的程序使用 - 例如,MediaWiki 实例(运行维基百科的软件)中的所有媒体文件(例如图像)。这是维基百科上的 Stack Overflow 徽标:

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

看到网址中的

0/02

了吗?就是那个桶。维基百科中的所有文件都将通过某种算法进行

hashed
- 例如 sha256,尽管不一定是这样 - 并且 02 将是该哈希的前两个十六进制数字。 (斜杠之前的
0
只是
02
的第一个数字;在本例中,它用作第二级分桶。)
如果 MediaWiki 只是将每个文件存储在一个庞大的目录中,则访问该目录中的文件会非常慢,因为尽管操作系统文件夹可以容纳任意多个文件,但它们的设计目的是不能容纳超过几千个文件或者。通过

散列

文件的内容,您会得到看起来像该文件唯一的十六进制数字的随机字符串,如果您随后将所有以相同的前两个十六进制数字开头的文件(例如02)放入名为

02
的文件夹,您将获得 256 个文件夹(前两个十六进制数字的每个可能值都有一个文件夹),并且至关重要的是,
这 256 个文件夹中的每一个都包含大致相等数量的文件
当您尝试查找特定文件(例如 MediaWiki)时,如果您以这种方式存储文件,您显然需要知道哈希值才能访问该文件。但就您而言,您只想加载

随机

文件。所以这也同样有效:

对所有文件进行哈希处理并对其进行存储(可能具有附加级别,例如,您可能需要像
    12/34/1234xxxx.ext
  • 这样的文件,这样您就有 65,536 个存储桶)。您可以使用
    hashlib
    sha256sum 等命令行工具来获取文件哈希值。您不需要重命名文件,只要根据其哈希值的前几个十六进制数字将它们分组到目录中即可。
    现在,每次您需要随机文件时,请选择一个随机存储桶(如果您使用其他级别,则可能是随机子存储桶),然后在该存储桶中选择一个随机文件。
  • 这样做比在包含一百万个文件的目录上使用
listdir

然后在其中随机选择要快得多。



注意:我在这里只是使用 MediaWiki 作为示例,因为我熟悉它的一些内部结构;很多软件产品都做类似的事情。

© www.soinside.com 2019 - 2024. All rights reserved.