微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

两个大向量之间的元素比较,高度稀疏

如何解决两个大向量之间的元素比较,高度稀疏

需要一个执行类似于 numpy.where 函数函数,但不会遇到由布尔数组的密集表示引起的内存问题。因此,该函数应该能够返回一个极其稀疏的布尔数组。

虽然下面给出的示例适用于小数据集/向量,但一旦 numpy.where 是 - 例如 - 形状为 my_sample 和 {{ 1}} 的形状为 (10.000.000,1)。阅读其他线程后,my_population 显然在评估表达式 (100.000,1) 时创建了一个形状为 numpy.where 的密集布尔数组。这个密集的 (10.000.000,100.000) 数组无法放入我的机器/大多数机器的内存中。

生成的数组非常稀疏。就我而言,知道每行最多有两个 1!使用上述规范,稀疏度等于 0.002%。这绝对应该适合内存。

尝试为数值模拟创建类似于模型/设计矩阵的东西。生成的矩阵将用于一些线性代数运算。

最小工作示例:请注意向量中的位置/坐标很重要。

numpy.where((my_sample == my_population.T))

解决方法

首先,让我们将其编码为整数,而不是字符串。字符串很糟糕。

pop_levels,pop_idx = np.unique(my_population,return_inverse=True)
sample_levels,sample_idx = np.unique(my_sample,return_inverse=True)

pop_levelssample_levels 必须相同,但如果相同,您就大功告成了 - 将它们打包成稀疏掩码:

sample_mask = sps.csr_matrix((np.ones_like(sample_idx),sample_idx,range(len(sample_idx) + 1)))

我们完成了:

>>> sample_mask.A
array([[1,0],[0,1,1],[1,0]])

您可能需要对因子水平重新排序,以使它们在样本和总体之间保持相同,但只要您可以统一这些标签,只需矩阵分配就很容易做到。

,

更直接的路线:

In [125]: my_sample = ['a','b','c','a']
     ...: my_population = ['a','c']
     ...: 
     ...: 
In [126]: np.array(my_sample)[:,None]==np.array(my_population)
Out[126]: 
array([[ True,False,False],[False,True,True],[ True,False]])

这是一个布尔数据类型。如果你想要 0/1 整数矩阵:

In [128]: (np.array(my_sample)[:,None]==np.array(my_population)).astype(int)
Out[128]: 
array([[1,0]])

如果你有空间来制作my_zero,你应该有空间来制作这个数组。如果大的临时缓冲区仍然存在问题,您可以尝试转换为'uint8',它占用的空间更少。

在您的版本中,您制作了两个大数组,my_zeromy_sample == my_population.T。但请注意,即使您通过了这一步,您也可能没有空间使用 my_zero 执行任何其他操作。

创建稀疏矩阵可以节省空间,但稀疏度必须非常高才能保持任何速度。尽管矩阵乘法对于 scipy.sparse 矩阵来说是一个相对强大的领域。

时间测试

In [134]: %%timeit
     ...: pop_levels,return_inverse=True)
     ...: sample_levels,return_inverse=True)
     ...: sample_mask = sparse.csr_matrix((np.ones_like(sample_idx),range(len(s
     ...: ample_idx) + 1)))

247 µs ± 195 ns per loop (mean ± std. dev. of 7 runs,1000 loops each)

In [135]: timeit (np.array(my_sample)[:,None]==np.array(my_population)).astype(int)
9.61 µs ± 9.4 ns per loop (mean ± std. dev. of 7 runs,100000 loops each)

并从密集矩阵中创建一个稀疏矩阵:

In [136]: timeit sparse.csr_matrix((np.array(my_sample)[:,None]==np.array(my_population)).as
     ...: type(int))
332 µs ± 1.44 µs per loop (mean ± std. dev. of 7 runs,1000 loops each)

大型数组的缩放可能会大不相同。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。