Setting numpy array to slice without any in-place operations

Viewed 118

How can I do this operation efficiently without any inplace operations?

n_id = np.random.choice(np.arange(2708), size=100)
z = np.random.rand(100, 64)
z_sparse = np.zeros((2708,64))
z_sparse[n_id[:100]] = z

Essentially I want the n_id rows of z_sparse to contain z's rows, but I can't do any inplace operations because my end goal is to use this in a pytorch problem.

One though would be to create zero rows within z precisely so that the rows of z end up in the positions n_id, but not sure how this would work efficiently.

Essentially row 1 of z should be placed at row n_id[0] of z_sparse, then row 2 of z should be at row n_id[1] of z_sparse, and so on...

Here's the PyTorch error jic you are curious: RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation

1 Answers

If n_id is a fixed index array, you can get z_sparse as a matrix multiplication:

# N, n, m = 2078,100, 64
row_mat = (n_id[:n] == np.arange(N)[:,None])

# for pytorch tensor
# row_mat = Tensor(n_id[:n] == np.arange(N)[:,None])

z_sparse =  row_mat @ z

Since row_mat is a constant array (tensor), your graph should work just fine.

Related