Yamu
Yamu

Reputation: 23

Numpy create matrix with values in specific locations

I would like to create a sparse matrix with values of 1 in specific locations. Is there a way to do that in numpy?

For instance, if I have a list a = [6,8,8,10,10,8,8,6], I would like to create a matrix of dimensions (len(a),max(a)) that looks like:

[[0,0,1,1,1,1,1,1,0,0],
 [0,1,1,1,1,1,1,1,1,0],
 [0,1,1,1,1,1,1,1,1,0],
 [1,1,1,1,1,1,1,1,1,1],
 [1,1,1,1,1,1,1,1,1,1],
 [0,1,1,1,1,1,1,1,1,0],
 [0,1,1,1,1,1,1,1,1,0],
 [0,0,1,1,1,1,1,1,0,0],
]

Basically it is a numpy.zeros((len(a),max(a))) matrix with ones in locations specified by the list a.

I am trying to use pad, but I can't seem to figure out a way to do it.

Upvotes: 2

Views: 131

Answers (2)

Divakar
Divakar

Reputation: 221554

Here's a vectorized approach using NumPy broadcasting -

arr = np.array(a)
N = arr.max()
Nr = np.arange(N)
diffs = (N - arr)//2
out = (((arr + diffs)[:,None] > Nr) & (diffs[:,None] <= Nr)).astype(int)

Please note that for an odd number in a, it would have one more zero on the right side bunch than one on the left. Here's a sample run to illustrate that -

In [55]: a
Out[55]: [6, 8, 8, 10, 10, 8, 8, 5] # last element changed to 5

In [56]: arr = np.array(a)
    ...: N = arr.max()
    ...: Nr = np.arange(N)
    ...: diffs = (N - arr)//2
    ...: out = (((arr + diffs)[:,None] > Nr) & (diffs[:,None] <= Nr)).astype(int)
    ...: 

In [57]: out
Out[57]: 
array([[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 0, 1, 1, 1, 1, 1, 0, 0, 0]])

Upvotes: 2

Colonel Beauvel
Colonel Beauvel

Reputation: 31171

One way would be - provided you only have even numbers:

import numpy as np

def func(i, m):
    arr = np.repeat(0, (m-i)/2)
    np.concatenate([arr, np.repeat(1, i), arr])

np.vstack([func(i, max(a)) for i in a])

Out[118]:
array([[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 0, 0]])

Upvotes: 1

Related Questions