切片的{numpy / tensorflow矢量化

时间:2017-10-02 17:54:56

标签: python arrays numpy vectorization

我在不同的时间管理一组大的仓位,作为稀疏矩阵:一组位置(列)和一组具有相同大小的时间。 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]

编辑以提供可运行的示例。

1 个答案:

答案 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])