Python scipy中无替换的缓慢随机样本生成

Python scipy中无替换的缓慢随机样本生成,python,random,scipy,hashmap,sparse-matrix,Python,Random,Scipy,Hashmap,Sparse Matrix,我试图创建随机散列映射h:[n]->[t]的稀疏矩阵表示,它映射每个I 精确地确定可用d位置的s随机位置,并从一些离散分布中提取这些位置的值 :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() distributio

我试图创建随机散列映射h:[n]->[t]的稀疏矩阵表示,它映射每个I 精确地确定可用d位置的s随机位置,并从一些离散分布中提取这些位置的值

: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%的时间用于生成行索引。我能做些什么来加快速度吗?还有别的选择吗?谢谢

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)
我认为是从
\u d
\n
次中选取
\u s
值。沿执行“无替换”,但允许在
\n
上进行替换可能很棘手

没有亲自运行代码(使用较小的
n
),我有点结结巴巴。生成
,还是生成最终的
csr
,哪个是慢的部分?在
n=500000
上的迭代将很慢

矩阵将是(1000500000),但包含(10*500000)个非零项。因此,稀疏度为0.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
因此,是的,大型迭代循环是昂贵的。但考虑到替代政策,可能没有办法解决这一问题。还是有

首先,创建
需要一半的时间,创建稀疏矩阵需要另一半的时间。我并不惊讶。您使用的是
coo
输入风格,在转换为
csr
时需要
lexsorting
并求和重复项。我们可以通过使用
indptr
类型的输入来提高速度。不会有重复的总和。由于每行始终有10个非零项,因此生成
indptr
值并不困难。但我不能一下子就这么做。(哦,这是转置)

random
稀疏到
csr
只是稍微慢一点:

In [11]: %timeit sparse.random(1000, 500000, .01, 'csr')
1 loop, best of 3: 28.3 s per loop

谢谢是,生成行索引需要90%的时间。你有没有想到其他的方法可以帮助你解决这个问题?我的意思是这对我来说太慢了。