我在不同的时间管理一组大的仓位,作为稀疏矩阵:一组位置(列)和一组具有相同大小的时间。 E.g。
matrix = numpy.random.randint(2, size = 100).astype(float).reshape(10,10)
times = numpy.nonzero(matrix)[0]+1
positions = numpy.nonzero(matrix)[1]
现在我必须以与时间相关的速度来纠正位置。问题是作为稀疏矩阵,我必须将与时间相关的速度扩展到给定时间的每个位置(即,给定行中的每个非零元素)。我知道在agiven时间的第一个pisition的索引和次数nTimes
如何对此代码进行矢量化(即删除循环)?
indexes = numpy.where(numpy.diff(times)>0)[0]+1
indexes = numpy.concatenate(([0],indexes, [times.size]))
nTimes = numpy.size(indexes)-1
speeds = numpy.random.rand(nTimes)
starts = indexes[:-1]
ends = indexes[1:]
expandedSpeeds = numpy.zeros(positions.size)
for i in numpy.arange(0,nTimes):
expandedSpeeds[starts[i]:ends[i]] = speeds[i]
编辑以提供可运行的示例。
答案 0 :(得分:1)
我试图功能化原始方法,这就是我得到的 -
def slices2arr_org(ar, starts, ends, N):
out0 = np.zeros((N),dtype=ar.dtype)
for i in np.arange(n_grp):
out0[starts[i]:ends[i]] = ar[i:i+1]
return out0
现在要对它进行矢量化,我们可以使用累积求和和一些掩蔽,就像这样 -
def slices2arr_vect(ar, starts, ends, N):
id_arr = np.zeros((N),dtype=int)
id_arr[starts[1:]] = 1
c = id_arr.cumsum()
np.add.at(id_arr, ends[1:],-1)
out = np.where(id_arr.cumsum()==0, 0, ar[c])
out[starts[0]:ends[0]] = ar[0]
return out
这是一个让事情更清晰的样本 -
In [677]: # Setup inputs
...: np.random.seed(0)
...: n_grp = 5
...: N = 15
...: idx = np.sort(np.random.choice(N, n_grp*2, replace=0))
...: starts, ends = idx[::2], idx[1::2]
...: ar = np.random.randint(11,99,(N))
...:
In [678]: ar
Out[678]: array([76, 50, 98, 57, 92, 48, 36, 88, 83, 20, 31, 91, 80, 90, 58])
In [679]: starts
Out[679]: array([ 1, 4, 7, 9, 13])
In [680]: ends
Out[680]: array([ 2, 6, 8, 10, 14])
In [681]: slices2arr_org(ar, starts, ends, N)
Out[681]: array([ 0, 76, 0, 0, 50, 50, 0, 98, 0, 57, 0, 0, 0, 92, 0])
In [682]: slices2arr_vect(ar, starts, ends, N)
Out[682]: array([ 0, 76, 0, 0, 50, 50, 0, 98, 0, 57, 0, 0, 0, 92, 0])