您在任何情况下都会遇到问题。正如
Roland Smith
在他的答案中所示,数据量和计算次数都非常巨大。您可能对线性代数不是很熟悉,因此需要一些解释来帮助您理解(然后希望解决)这个问题。
您的数组都是长度为100的向量集合。其中一个数组有300,000个向量,另一个数组有1,000,000个向量。这两个数组之间的点积意味着您要计算每对向量的点积。这样的对数有300,000,000,000个,因此得到的矩阵无论使用32位还是64位浮点数,都是1.2 TB或2.4 TB。
在我的电脑上,将(300,100)的数组与(100,1000)的数组进行点乘需要大约1毫秒。推算一下,您需要1000秒的计算时间(取决于核心数量)。
点积的好处是可以逐步完成。然后保留输出是另一个问题。
如果您在自己的计算机上运行它,可以按以下方式计算结果矩阵:
- 将输出数组创建为
np.memmap
数组写入磁盘
- 按行逐个计算结果(由
Roland Smith
解释)
这将导致一个大文件的线性写入(2.4 TB)。
这不需要太多代码。但是,请确保以适当的方式转置一切;输入数组的转置很便宜,输出的转置非常昂贵。如果您可以访问彼此靠近的元素,则访问结果巨大的数组很容易,否则非常昂贵。
对于巨大的memmapped数组进行排序必须小心处理。您应该使用在连续数据块上操作的原地排序算法。数据存储在4 KiB块中(512或1024个浮点数),读取的块越少,效果越好。
现在,您不是在自己的机器上运行代码,而是在云平台上运行,情况发生了很大变化。通常,云SSD存储对随机访问非常快,但是IO代价高(也是金钱成本高)。可能最便宜的选项是计算适当大小的数据块并将其发送到S3存储以供进一步使用。 "适当大小" 的部分取决于您如何使用数据。如果您需要处理单个列,则每次将一个或几个列发送到云对象存储。
然而,很多事情取决于您的排序需求。您的代码看起来好像最终只查看每列的前几个项目。如果是这种情况,则应仅计算前几个项目而不是完整的输出矩阵。这样,您可以在内存中完成所有操作。
也许,如果您能更详细地说明您的排序需求,就可以找到可行的方法来实现您想要的结果。
哦,还有一件重要的事情:您的矩阵是密集的还是稀疏的?(稀疏意味着它们主要包含0。)如果您预计输出矩阵大部分都是零,那可能会完全改变游戏规则。
np.argpartition
,我认为它会节省你一些时间。关于其他建议,请参考:https://dev59.com/h2w05IYBdhLWcg3w_Gqw - user2379410