我正在尝试创建随机哈希映射h的稀疏矩阵表示:[n] - > [t]映射每个i 确切地说是可用d个位置的随机位置,并且这些位置的值是从一些离散分布中得出的。
:param d: number of bins
:param n: number of items hashed
:param s: sparsity of each column
:param distribution: distribution object.
这是我的尝试:
start_time=time.time()
distribution = scipy.stats.rv_discrete(values=([-1.0, +1.0 ], [0.5, 0.5]),name = 'dist')
data = (1.0/sqrt(self._s))*distribution.rvs(size=self._n*self._s)
col = numpy.empty(self._s*self._n)
for i in range(self._n):
col[i*self._s:(i+1)*self._s]=i
row = numpy.empty(self._s*self._n)
print time.time()-start_time
for i in range(self._n):
row[i*self._s:(i+1)*self._s]=numpy.random.choice(self._d, self._s, replace=False)
S = scipy.sparse.csr_matrix( (data, (row, col)), shape = (self._d,self._n))
print time.time()-start_time
return S
现在为n = 500000,s = 10,d = 1000创建这个地图,在我体面的工作站上花了大约20秒,其中90%的时间用于生成行索引。有什么办法可以加快速度吗?任何替代品?感谢。
答案 0 :(得分:1)
col = numpy.empty(self._s*self._n)
for i in range(self._n):
col[i*self._s:(i+1)*self._s]=i
看起来像可以写成一个非循环表达式的东西;虽然它可能不是消费者的大时间
我的第一个猜测是 - 但我需要玩这个才能确定;我认为它正在为列索引号分配所有行。
col = np.empty(self._s, self._n)
col[:,:] = np.arange(self._n)
col = col.ravel()
类似的东西:
for i in range(self._n):
row[i*self._s:(i+1)*self._s]=numpy.random.choice(self._d, self._s, replace=False)
我认为是从_s
_d
次中挑选_n
个值。 <_ 1}}允许替换_s,但是允许替换_n
可能会很棘手。
如果不自行运行代码(使用较小的n
),我就会磕磕绊绊。哪个是缓慢的部分,生成col
,row
或最终的csr
?对n=500000
的迭代将变慢。
矩阵将是(1000,500000),但是(10 * 500000)非零项。所以.01的稀疏性。仅仅为了比较,生成类似大小和稀疏度的稀疏随机矩阵将是有趣的
In [5]: %timeit sparse.random(1000, 500000, .01)
1 loop, best of 3: 24.6 s per loop
和密集的随机选择:
In [8]: timeit np.random.choice(1000,(10,500000)).shape
10 loops, best of 3: 53 ms per loop
In [9]: np.array([np.random.choice(1000,(10,)) for i in range(500000)]).shape
Out[9]: (500000, 10)
In [10]: timeit np.array([np.random.choice(1000,(10,)) for i in range(500000)]).
...: shape
1 loop, best of 3: 12.7 s per loop
所以,是的,大型迭代循环很昂贵。但鉴于替代政策可能没有办法解决这个问题。或者有吗?
首先猜测,创建row
需要一半的时间,另一半创建稀疏矩阵。我不惊讶。您正在使用coo
输入样式,这需要lexsorting
并在转换为csr
时对重复项求和。我们可以通过使用indptr
类型的输入来获得速度。总和不会有重复。而且由于每行始终有10个非零项,因此生成indptr
值并不难。但我无法做到这一点。 (哎呀,这就是转置)。
random
稀疏到csr
只是有点慢:
In [11]: %timeit sparse.random(1000, 500000, .01, 'csr')
1 loop, best of 3: 28.3 s per loop