Reputation: 17
I am looking for exact command in Numpy for following Matlab indexing.
Uploaded as picture: [1]: https://i.sstatic.net/Q2DJ0.png
I have tried to do similar thing in Numpy:
kk = np.zeros((100,100))
k= np.array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]])
kk[[9,2,7],[9,2,7]] = k
But this will throw you error:
ValueError: shape mismatch: value array of shape (3,3) could not be broadcast to indexing result of shape (3,)
i edit this question, in my case, each indexing is not contiguous, but they are the same for example: kk[[9,2,7],[9,2,7]].
Upvotes: 0
Views: 132
Reputation: 26886
If the indexing is contiguous you should use slice()
s:
import numpy as np
kk = np.zeros((6, 7), dtype=int)
k = np.arange(2 * 3).reshape((2, 3)) + 1
kk[1:3, 1:4] = k
print(kk)
# [[0 0 0 0 0 0 0]
# [0 1 2 3 0 0 0]
# [0 4 5 6 0 0 0]
# [0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0]]
Note that a:b:c
inside []
is sugar syntax for slice(a, b, c)
, with :c
/, c
optional and if a
/b
should be None
this can be left out in the shortcut (but not in the functional version) and if only one parameter is set to slice()
, this is assigned to b
.
Otherwise, you could use numpy.ix_()
:
import numpy as np
kk = np.zeros((6, 7), dtype=int)
k = np.arange(2 * 3).reshape((2, 3)) + 1
kk[np.ix_((1, 3), (1, 2, 4))] = k
print(kk)
# [[0 0 0 0 0 0 0]
# [0 1 2 0 3 0 0]
# [0 0 0 0 0 0 0]
# [0 4 5 0 6 0 0]
# [0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0]]
Slices are typically way faster and more memory efficient than advanced indexing, and you should prefer them when possible.
Note that np.ix_()
is just producing index arrays with the correct shapes to trigger the desired indexing:
np.ix_((1, 3), (1, 2, 4))
# (array([[1],
# [3]]), array([[1, 2, 4]]))
Hence, the following would work:
import numpy as np
kk = np.zeros((6, 7), dtype=int)
k = np.arange(2 * 3).reshape((2, 3)) + 1
kk[np.array([1, 3])[:, None], np.array([1, 2, 4])[None, :]] = k
print(kk)
# [[0 0 0 0 0 0 0]
# [0 1 2 0 3 0 0]
# [0 0 0 0 0 0 0]
# [0 4 5 0 6 0 0]
# [0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0]]
Also, slice
s and np.ndarray(dtype=int)
can be combined together:
import numpy as np
kk = np.zeros((6, 7), dtype=int)
k = np.arange(2 * 3).reshape((2, 3)) + 1
kk[1:4:2, np.array([1, 2, 4])] = k
print(kk)
# [[0 0 0 0 0 0 0]
# [0 1 2 0 3 0 0]
# [0 0 0 0 0 0 0]
# [0 4 5 0 6 0 0]
# [0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0]]
Upvotes: 1