两个大向量之间的逐元素比较,稀疏度高
Elementwise comparison between two large vectors, high degree of sparsity
需要一个与 numpy.where
函数执行类似的函数,但不会 运行 进入由布尔数组的密集表示引起的内存问题。因此,该函数应该能够 return 一个极其稀疏的布尔数组。
虽然下面给出的示例适用于小数据 sets/vectors,但一旦 my_sample
的形状为 (10.000.000, 1)
,就无法使用 numpy.where
函数] 和 my_population
的形状是 (100.000, 1)
。在阅读其他线程后,numpy.where
显然在计算表达式 numpy.where((my_sample == my_population.T))
时创建了一个形状为 (10.000.000, 100.000)
的密集布尔数组。这个密集的 (10.000.000, 100.000)
数组无法放入我的 machine/most 机器上的内存中。
生成的数组非常稀疏。在我的例子中,知道每行最多有两个 1!使用上面的规范,稀疏度等于 0.002%。这绝对适合记忆。
尝试为数值模拟创建类似于 model/design 矩阵的东西。生成的矩阵将用于一些线性代数运算。
最小工作示例:请注意向量中的 positions/coordinates 很重要。
# import packages
import numpy as np
# my_sample is the vector of observations
my_sample = ['a', 'b', 'c', 'a']
# my_population is the lookup vector
my_population = ['a', 'b', 'c']
# initalise the matrix (dense matrix for this exampe)
my_zero = np.zeros((len(my_sample), len(my_population)))
# reshape to arrays
my_sample = np.array(my_sample).reshape(-1, 1)
my_population = np.array((my_population)).reshape(-1, 1)
# THIS STEP CAUSES THE MEMORY ISSUES
my_indices = np.where((my_sample == my_population.T))
# set the matches to equal one
my_zero[my_indices] = 1
# show matrix
my_zero
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.],
[1., 0., 0.]])
首先,让我们将其编码为整数,而不是字符串。弦乐糟透了。
pop_levels, pop_idx = np.unique(my_population, return_inverse=True)
sample_levels, sample_idx = np.unique(my_sample, return_inverse=True)
重要的是 pop_levels
和 sample_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],
[0, 1, 0],
[0, 0, 1],
[1, 0, 0]])
您可能需要重新排序您的因子水平,以便它们在您的样本和总体之间相同,但只要您可以统一这些标签,这只需矩阵分配就可以非常简单地完成。
更直接的路线:
In [125]: my_sample = ['a', 'b', 'c', 'a']
...: my_population = ['a', 'b', 'c']
...:
...:
In [126]: np.array(my_sample)[:,None]==np.array(my_population)
Out[126]:
array([[ True, False, False],
[False, True, False],
[False, False, True],
[ True, False, False]])
这是一个布尔数据类型。如果你想要 0/1 整数矩阵:
In [128]: (np.array(my_sample)[:,None]==np.array(my_population)).astype(int)
Out[128]:
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[1, 0, 0]])
如果你有 space 来制作 my_zero
,你应该有 space 来制作这个数组。如果大的临时缓冲区仍然有问题,你可以尝试转换为 'uint8',这样占用更少 space.
在您的版本中,您制作了两个大数组,my_zero
和 my_sample == my_population.T
。但请注意,即使您通过了这一步,您也可能无法 space 对 my_zero
做任何其他事情。
创建稀疏矩阵可能会节省您 space,但稀疏度必须非常高才能保持任何速度。尽管矩阵乘法是 scipy.sparse
矩阵的相对强项。
时间测试
In [134]: %%timeit
...: pop_levels, pop_idx = np.unique(my_population, return_inverse=True)
...: sample_levels, sample_idx = np.unique(my_sample, return_inverse=True)
...: sample_mask = sparse.csr_matrix((np.ones_like(sample_idx), 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)
大型阵列的缩放可能完全不同。
需要一个与 numpy.where
函数执行类似的函数,但不会 运行 进入由布尔数组的密集表示引起的内存问题。因此,该函数应该能够 return 一个极其稀疏的布尔数组。
虽然下面给出的示例适用于小数据 sets/vectors,但一旦 my_sample
的形状为 (10.000.000, 1)
,就无法使用 numpy.where
函数] 和 my_population
的形状是 (100.000, 1)
。在阅读其他线程后,numpy.where
显然在计算表达式 numpy.where((my_sample == my_population.T))
时创建了一个形状为 (10.000.000, 100.000)
的密集布尔数组。这个密集的 (10.000.000, 100.000)
数组无法放入我的 machine/most 机器上的内存中。
生成的数组非常稀疏。在我的例子中,知道每行最多有两个 1!使用上面的规范,稀疏度等于 0.002%。这绝对适合记忆。
尝试为数值模拟创建类似于 model/design 矩阵的东西。生成的矩阵将用于一些线性代数运算。
最小工作示例:请注意向量中的 positions/coordinates 很重要。
# import packages
import numpy as np
# my_sample is the vector of observations
my_sample = ['a', 'b', 'c', 'a']
# my_population is the lookup vector
my_population = ['a', 'b', 'c']
# initalise the matrix (dense matrix for this exampe)
my_zero = np.zeros((len(my_sample), len(my_population)))
# reshape to arrays
my_sample = np.array(my_sample).reshape(-1, 1)
my_population = np.array((my_population)).reshape(-1, 1)
# THIS STEP CAUSES THE MEMORY ISSUES
my_indices = np.where((my_sample == my_population.T))
# set the matches to equal one
my_zero[my_indices] = 1
# show matrix
my_zero
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.],
[1., 0., 0.]])
首先,让我们将其编码为整数,而不是字符串。弦乐糟透了。
pop_levels, pop_idx = np.unique(my_population, return_inverse=True)
sample_levels, sample_idx = np.unique(my_sample, return_inverse=True)
重要的是 pop_levels
和 sample_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],
[0, 1, 0],
[0, 0, 1],
[1, 0, 0]])
您可能需要重新排序您的因子水平,以便它们在您的样本和总体之间相同,但只要您可以统一这些标签,这只需矩阵分配就可以非常简单地完成。
更直接的路线:
In [125]: my_sample = ['a', 'b', 'c', 'a']
...: my_population = ['a', 'b', 'c']
...:
...:
In [126]: np.array(my_sample)[:,None]==np.array(my_population)
Out[126]:
array([[ True, False, False],
[False, True, False],
[False, False, True],
[ True, False, False]])
这是一个布尔数据类型。如果你想要 0/1 整数矩阵:
In [128]: (np.array(my_sample)[:,None]==np.array(my_population)).astype(int)
Out[128]:
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[1, 0, 0]])
如果你有 space 来制作 my_zero
,你应该有 space 来制作这个数组。如果大的临时缓冲区仍然有问题,你可以尝试转换为 'uint8',这样占用更少 space.
在您的版本中,您制作了两个大数组,my_zero
和 my_sample == my_population.T
。但请注意,即使您通过了这一步,您也可能无法 space 对 my_zero
做任何其他事情。
创建稀疏矩阵可能会节省您 space,但稀疏度必须非常高才能保持任何速度。尽管矩阵乘法是 scipy.sparse
矩阵的相对强项。
时间测试
In [134]: %%timeit
...: pop_levels, pop_idx = np.unique(my_population, return_inverse=True)
...: sample_levels, sample_idx = np.unique(my_sample, return_inverse=True)
...: sample_mask = sparse.csr_matrix((np.ones_like(sample_idx), 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)
大型阵列的缩放可能完全不同。