Python中的快速数据结构,用于将一堆图像索引为重复项

Posted

技术标签:

【中文标题】Python中的快速数据结构,用于将一堆图像索引为重复项【英文标题】:Fast data structure in Python for indexing a bunch of images as duplicates 【发布时间】:2019-09-05 07:53:45 【问题描述】:

简介:我想用相应的 TEX 代码替换 Encyclopedia of Mathematics 上大约 280,000 张数学公式的图像。为此,我将所有这些图像(或者更好的是:它们的 URL)分类到一个包含 100'000 个列表的列表中。

每个“子列表”都包含 url 字符串,这样子列表中的每个 url 都链接到同一个图像。该列表类似于[["https://www.encyclopediaofmath.org/legacyimages/a/a130/a130010/a1300105.png", "https://www.encyclopediaofmath.org/legacyimages/a/a010/a010080/a01008021.png", ...], ["https://www.encyclopediaofmath.org/legacyimages/w/w130/w130080/w1300801.png", "https://www.encyclopediaofmath.org/legacyimages/w/w130/w130080/w130080211.png"], ...]

对于每个子列表,我已经(或仍在处理中)为该子列表的一个图像确定了相应的 TEX 代码。由于每个子列表中的图像都是相同的,我已经(或仍然)确定了整个列表中每个图像 url 的 TEX 代码。

现在我想用已知的 TEX 代码替换每篇文章中的图像(例如this one)。这导致我不得不在这个子列表列表中索引每篇文章的图像 URL。

我的问题:对于上述任务,您知道比列表列表更好的数据结构吗?

示例代码:

dups = [[i, i+1] for i in range(100000)]
for i in range(10000):
    for j in range(100000):
        if i in dups[j]:
            print(f"Found number i in j-th list")
            break

在上面的例子中,dups 是我的列表列表的简化版本(我使用的是数字而不是字符串。)如您所见,上述程序需要一些时间才能完成。我想改进 dups,以便可以更快地完成类似类型的索引。

备注 1: 如果 dups 的长度为 n,则上述代码实质上会进行 1 + 2 + 3 + ... + n 次比较。这导致 n * (n+1)/2 次比较。由于在我的情况下 n = 100'000,这已经是很多比较了。

备注 2: 一个明显的改进是将每个子列表转换为 Python 集合并考虑集合列表。但是,我的大多数子列表包含的图像少于 3 张,所以我怀疑这会大大提高运行时间。

备注 3: 请注意,我几乎无法控制“传入”图像的顺序(基本上我必须遵循文章结构),并且我无法在列表中构建完整的顺序列表(因为我无法将子列表分开。)因此我还没有找到实现二进制搜索的方法。

【问题讨论】:

【参考方案1】:

虽然它可能会引入数据冗余,但我建议使用二叉搜索树。您的列表列表是索引的好主意,但它有一个重要问题,确实是运行时。

您对树的度量可能只是链接的字母比较(a z 等)。因此,基本上你有二进制搜索和一些冗余数据。如果我们算一下,您有 280,000 张图像,这意味着 BST 中的平均搜索时间为log[2](280,000),大约是 18 步。考虑到速度的提高,你有大约三个相同的 TEX 代码真的没关系,只需存储 3 次即可。将其视为键值对。在您的 BST 中,关键是您的链接,相应的值只是与它一起存储(您可以使用您的列表列表)。您也可以将您的对的值作为它所在的子列表的索引。但我的一般建议是在搜索时忽略您的子列表,并在完成后再次使用它们。

一棵树看起来像这样:

                                (link, code/index)
                              /                     \
                      (link,code/index)       (link, code/index)
                            / \                      / \
                            etc.                     etc.

如果您想或必须坚持您的子列表想法,那么我唯一的建议是根据您的列表创建一个dictionary。请参阅此处了解其中的time complexity。

如果可能的话,我会实现这个in a language which has pointers 或以这样一种方式,即每个链接的代码都是同一个对象以节省空间。

【讨论】:

我喜欢树的想法,我认为它甚至可以在 Python 中实现。由于列表不可散列,我想我必须通过它们的 TEX 代码来索引字典中的列表?无论如何,只要没有人提出其他开创性的建议,我很快就会接受这个答案:D @MaximilianJanisch 也许我理解错了,但是用 TEX 代码索引列表听起来有点奇怪。虽然列表不可散列,但字符串可以!也许看看这样的东西:sublist A = [l1,l2,l3](比如说\Alpha)现在我们构建一个字典dict = l1: "\Alpha",. l2: "\Alpha", l3: "\Alpha", ... (other stuff here)。这将允许您简单地输入一个链接并取回代码。占用大量内存,但访问速度很快。也许也只使用图像的文件路径来使事情变得更快(即只是不同的部分)。 字典听起来也很容易实现!此外,我认为它不会大大改变我的存储使用情况(无论如何在这种情况下它并不重要),因为我只需要存储大约 180000 个 TEX 代码

以上是关于Python中的快速数据结构,用于将一堆图像索引为重复项的主要内容,如果未能解决你的问题,请参考以下文章

将一列时间戳转换为 pandas 中的句点

Unity ShaderSpecial EffectsCorrect 色彩修正(UI)

Unity ShaderSpecial EffectsCorrect 色彩修正(UI)

Unity ShaderSpecial EffectsCorrect 色彩修正(UI)

Unity ShaderSpecial EffectsCorrect 色彩修正(UI)

Unity ShaderSpecial EffectsCorrect 色彩修正(UI)