Incubator-mxnet: why mxnet ndarray not support multi-dimension indexing ?

Created on 10 Apr 2017  路  5Comments  路  Source: apache/incubator-mxnet

a = mx.nd.ones((2,3))
a[:,0] multi-dimension indexing is not supported

Most helpful comment

use slice

All 5 comments

use slice

@piiswrong What if I want to assign something into the sliced array? For example,
a[:, 0] = 2

I have a simmilar question to itijyou. Is there an assignment analog to the ndarray.take function ?
For example, lets take a simple case of sorting, where we take an array 'a', and attempt to set the 4 lowest valued indices to 0. The last step 'a[c] = 0' does not throw an error, however it also does not perform the assignment to 'a'.

python

import mxnet as mx
import numpy as np
a = mx.nd.array(np.array([1,4,6,2,4,5,6,2]))
a.asnumpy()
array([ 1., 4., 6., 2., 4., 5., 6., 2.], dtype=float32)

sort the array and find the indices of the 4 lowest valued entries

b = mx.nd.argsort(a)
b.asnumpy()
array([ 0., 3., 7., 1., 4., 5., 2., 6.], dtype=float32)
c=b[0:4]
c.asnumpy()
array([ 0., 3., 7., 1.], dtype=float32)

ndarray.take() can be used to read the values in 'a' corresponding to the indices in 'c'

d = mx.nd.take(a,c)
d.asnumpy()
array([ 1., 2., 2., 4.], dtype=float32)

How do we write to 'a' at the indices given by 'c'. Following does not work:

a[c] = 0
a.asnumpy()
array([ 1., 4., 6., 2., 4., 5., 6., 2.], dtype=float32)

Any help or alternative would be helpful. The only alternative I can think of is the following, which is ugly and does not really work well if the values in 'a' are not unique:

select the 4th smallest element

c=b[4]
c.asnumpy()
array([ 4.], dtype=float32)
d = mx.nd.take(a,c)
d.asnumpy()
array([ 4.], dtype=float32)

create a binary mask of all elements larger than the 4th smallest element

mask = a > d
mask.asnumpy()
array([ 0., 0., 1., 0., 0., 1., 1., 0.], dtype=float32)
mask = 1-mask
mask.asnumpy()
array([ 1., 1., 0., 1., 1., 0., 0., 1.], dtype=float32)
e = a * mask
e.asnumpy()
array([ 1., 4., 0., 2., 4., 0., 0., 2.], dtype=float32)

As you see, there is an extra '4' in the 'e' result.

My real life application is to perform hard negative sampling based on the loss values. For example, I have a 60x40 loss matrix, and I need to find the top 100 loss values, and set the gradients corresponding to the rest to 0. I can do this easily in numpy but would prefere a pure mx.ndarray based solution.

I agree. Slice is useful for reading values, but not for assigning values. Any suggestion? @piiswrong @mli

@horserma @itijyou
Assigning operation is prohibited in functional programming. You can create a new node instead assign values to old ones.
By the way, I found mxnet.symbol.pick/mxnet.ndarray.pick are really convenient for indexing. But, I still hope MXNET could have APIs for indexing like numpy.

Was this page helpful?
0 / 5 - 0 ratings