Create a matrix with a matrix with elements - index function

How to create a numpy matrix with its elements being a function of its indices? For example, the multiplication table:a[i,j] = i*j

Un-numpy and un-pythonic would have to create an array of zeros and then loop through.

There is no doubt that this is the best way to do this without a loop.

However, it would be even better to create the matrix immediately.

Thanks in advance for your suggestions.

+3
source share
4 answers

I'm currently far from my python, but does it work?

array( [ [ i*j for j in xrange(5)] for i in xrange(5)] )
+3
source

Here is one way to do this:

>>> indices = numpy.indices((5, 5))
>>> a = indices[0] * indices[1]
>>> a
array([[ 0,  0,  0,  0,  0],
       [ 0,  1,  2,  3,  4],
       [ 0,  2,  4,  6,  8],
       [ 0,  3,  6,  9, 12],
       [ 0,  4,  8, 12, 16]])

Next, it numpy.indices((5, 5))generates two arrays containing the x and y indices of the 5x5 array, for example:

>>> numpy.indices((5, 5))
array([[[0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3],
        [4, 4, 4, 4, 4]],

       [[0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4]]])

, numpy .

+7

np.multiply.outer(np.arange(5), np.arange(5))  # a_ij = i * j

and generally speaking

np.frompyfunc(
    lambda i, j: f(i, j), 2, 1
).outer(
    np.arange(5),
    np.arange(5),
).astype(np.float64)  # a_ij = f(i, j)

basically you create np.ufuncthrough np.frompyfuncand then outerwith indexes.

Edit

Speed ​​comparison between different solutions.

Small matrices:

Eyy![1]: %timeit np.multiply.outer(np.arange(5), np.arange(5))
100000 loops, best of 3: 4.97 µs per loop

Eyy![2]: %timeit np.array( [ [ i*j for j in xrange(5)] for i in xrange(5)] )
100000 loops, best of 3: 5.51 µs per loop

Eyy![3]: %timeit indices = np.indices((5, 5)); indices[0] * indices[1]
100000 loops, best of 3: 16.1 µs per loop

Large matrices:

Eyy![4]: %timeit np.multiply.outer(np.arange(4096), np.arange(4096))
10 loops, best of 3: 62.4 ms per loop

Eyy![5]: %timeit indices = np.indices((4096, 4096)); indices[0] * indices[1]
10 loops, best of 3: 165 ms per loop

Eyy![6]: %timeit np.array( [ [ i*j for j in xrange(4096)] for i in xrange(4096)] )
1 loops, best of 3: 1.39 s per loop
+4
source

Just wanted to add that @Senderle's answer can be generalized to any function and dimension:

dims = (3,3,3) #i,j,k
ii = np.indices(dims)

Then you can calculate a[i,j,k] = i*j*khow

a = np.prod(ii,axis=0)

or a[i,j,k] = (i-1)*j*k:

a = (ii[0,...]-1)*ii[1,...]*ii[2,...]

etc.

+2
source

All Articles