Reputation: 2921
Let there be a numpy array of shape [M], dtype int32 and (random) values in range [0, N), e.g.:
M = 8
N = 5
a = np.random.randint(0, N, [M]) # a = [1, 1, 2, 4, 0, 1, 1, 3]
From this array I need to create a matrix m of shape [M, N], dtype int32 and values 0 or 1, where m[i,j] = 0 if j < a[i], otherwise 1. Following the example:
m = some_magic(a) # m = [[0, 1, 1, 1, 1],
# [0, 1, 1, 1, 1],
# [0, 0, 1, 1, 1],
# [0, 0, 0, 0, 1],
# [1, 1, 1, 1, 1],
# [0, 1, 1, 1, 1],
# [0, 1, 1, 1, 1],
# [0, 0, 0, 1, 1]]
My dysfunctional version of some_magic starts with initializing the matrix to zeros (using np.zeros), and then proceeding to set the appropriate members to 1.
m = np.zeros([M, N])
This next part though I cannot properly figure out. Accessing single members, for example, every second member, or a fixed slice, is easy, and achievable by
m[np.arange(M), C1:C2]
where C1 and C2 are integer constants,
m[np.arange(M), a:]
which, as far as I've thought, should yield the correct result, fails with the error being
Only integer scalar arrays can be converted to a scalar index.
Can you please point me to the right direction? Thank you very much.
Upvotes: 1
Views: 209
Reputation: 51155
Here's a solution using broadcasting
.
(a[:, None] <= np.arange(N)).view('i1')
# np.less_equal.outer(a, np.arange(N)).view('i1')
array([[0, 1, 1, 1, 1],
[0, 1, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[0, 1, 1, 1, 1],
[0, 1, 1, 1, 1],
[0, 0, 0, 1, 1]], dtype=int8)
Upvotes: 1
Reputation: 4699
I'm not sure if slicing like that is possible. I suggest you create indices instead and then operate on those:
M = 8
N = 5
#a = np.random.randint(0, N, [M])
a = np.array([1, 1, 2, 4, 0, 1, 1, 3])
from0toN = np.expand_dims(np.arange(N),0) # [[0,1,2,3,4]]
m = np.repeat(from0toN, M, axis=0)
#array([[0, 1, 2, 3, 4],
# ...,
# [0, 1, 2, 3, 4]])
boolean = m >= np.expand_dims(a,1)
onesAndZeroes = boolean.astype(int)
"""
array([[0, 1, 1, 1, 1],
[0, 1, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[0, 1, 1, 1, 1],
[0, 1, 1, 1, 1],
[0, 0, 0, 1, 1]])
"""
Upvotes: 0