Python 存储数百万个阵列并在检查中执行的有效方法

Python 存储数百万个阵列并在检查中执行的有效方法,python,arrays,algorithm,Python,Arrays,Algorithm,大约有300万个数组或Python列表\元组(其实并不重要)。每个数组由以下元素组成: ['string1', 'string2', 'string3', ...] # totally, 10000 elements 这些数组应该存储在某种键值存储中。为了简单的解释,现在让我们假设它是Python的dict 300万个键,每个键代表一个10000个元素的数组 列表\元组或任何其他自定义内容-这并不重要。重要的是数组应该由字符串组成——utf8或unicode字符串,每个字符串的字符数从5个到

大约有300万个数组或Python列表\元组(其实并不重要)。每个数组由以下元素组成:

['string1', 'string2', 'string3', ...]  # totally, 10000 elements
这些数组应该存储在某种键值存储中。为了简单的解释,现在让我们假设它是Python的dict

300万个键,每个键代表一个10000个元素的数组

列表\元组或任何其他自定义内容-这并不重要。重要的是数组应该由字符串组成——utf8或unicode字符串,每个字符串的字符数从5个到50个左右。还有大约300万个可能的字符串。如果真的需要的话,可以用整数替换它们,但是为了更有效的进一步操作,我更喜欢使用字符串

虽然很难给出数据的完整描述(它既复杂又奇怪),但它类似于同义词——假设我们有300万个单词——作为dict键——以及每个单词或列表元素的10k同义词

这样(不是真正的同义词,但它会让你产生想法):

元素-“同义词”-可以根据需要进行排序

之后,在填充数组之后,会有一个循环:我们遍历所有键并检查某个var是否在其值中。例如,用户输入单词‘computer’和‘laptop’——如果单词‘laptop’是单词‘computer’的同义词,我们必须快速回复。这里的问题是,我们必须检查它数百万次,可能是2000万左右。试想一下,我们有很多用户输入一些随机的单词——“计算机”、“汽车”、“电话”和“建筑”等等。他们可能“匹配”,也可能不“匹配”

总之,我需要的是:

  • 有效地将这些数据结构存储在内存中
  • 能够快速检查数组中是否有某个项目
我应该能够保持内存使用低于30GB。而且我应该能够在Xeon CPU上在不到10小时内执行所有迭代

有大约0.1%的错误答案是可以的,不管是肯定的还是否定的,尽管最好是减少错误答案,或者干脆不要错误答案


这里最好的方法是什么?算法,代码链接,任何东西都值得欣赏。还有——我的一个朋友建议使用bloom过滤器或marisa在这里尝试——他说得对吗?我没有和他们一起工作。

为什么要维护自己的内存数据结构?为什么不为此使用常规数据库?如果速度太慢,为什么不使用内存中的数据库呢?一种解决方案是在内存中使用
sqlite3
。选中此SO链接,例如:

通过将
':memory:'
传递到
connect
方法,可以创建内存中的数据库

import sqlite3
conn = sqlite3.connect(':memory:')
你的模式是什么?我可以想到一个宽泛的模式,用一个字符串作为
id
键(例如示例中的“computer”、“house”和大约10000个额外的列:“field1”到“field10000”;数组中的每个元素都有一个)。构建模式后,在数据库中迭代插入数据将非常简单:每行数据一条SQL语句。根据您的描述,
插入部分仅为一次。数据库没有进一步的修改

最大的问题是检索(更关键的是检索速度)。为单个键(如
computer
)检索整个数组也是一条简单的SQL语句。可伸缩性和速度是我不知道的,这是你必须去尝试的。内存数据库仍有希望加快检索部分的速度。然而,我相信这是您可以实现和测试的最便宜、最快的解决方案(比多节点集群便宜得多)


我为什么要提出这个解决方案?因为您心目中的设置与快速增长的数据库支持的互联网初创公司非常相似。所有优秀的初创公司每天都有相似数量的请求;使用某种带有缓存的数据库(如果一个简单的数据库不能扩展到百万个请求,那么缓存将是下一个查找问题的方法。同样,它比购买RAM/节点更简单、更便宜)

我会将每个唯一的字符串映射到一个数字ID,然后将a与每个元素的大约20位相关联,以供您选择。您需要将它们保存在RAM中吗?我会研究一些类似HDF5的文件,它们是为这种用途而设计的。(好吧,HDF5不适合你,因为它是用于数字数据的,但你明白了)@RicardoCárdenes好吧,使用HDD的单节点集群的工作速度太慢了。磁盘操作非常慢。我怀疑即使是SDD也会有很大帮助。另外,我不想让事情复杂化,也不想创建多节点集群。如果可以避免这样做,并将所有内容都保存在RAM中,那么应该是这样。你所说的“10小时内的所有迭代”是什么意思?另外,“30GB以下的内存使用率”是指整个数据结构吗?这将是困难的,因为只存储字符串,不考虑映射到哪个,在没有压缩的情况下将占用超过100GB的空间。你为NSA工作吗?;-)如果某些单词的同义词少于10000个,这可能会浪费内存。根据他的描述,数据的结构似乎正好是10k条记录。如果数量较少,细节将很重要。如果有大量的记录,我们仍然可以保持内存效率。谢谢这个想法。虽然我认为redis会更快,不是吗?它必须更快,开销也必须更小,这仅仅是因为它缺少RDBMS功能,如过滤、排序、连接等。但即使使用Redis,它也不会非常快速和紧凑-需要找到一种减少阵列大小的方法,以便bloom过滤器可能会有所帮助
import sqlite3
conn = sqlite3.connect(':memory:')