Create a numpy matrix with elements as a function of indices

前端 未结 5 915
迷失自我
迷失自我 2020-12-16 21:11

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

An Un-numpy and un-

相关标签:
5条回答
  • 2020-12-16 21:31

    For the multiplication

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

    and in general

    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 an np.ufunc via np.frompyfunc and then outer it with the indices.

    Edit

    Speed comparision between the 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
    

    Bigger 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
    
    0 讨论(0)
  • 2020-12-16 21:38

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

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

    You could then calculate a[i,j,k] = i*j*k as

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

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

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

    etc

    0 讨论(0)
  • 2020-12-16 21:40

    Here's one way to do that:

    >>> 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]])
    

    To further explain, numpy.indices((5, 5)) generates two arrays containing the x and y indices of a 5x5 array like so:

    >>> 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]]])
    

    When you multiply these two arrays, numpy multiplies the value of the two arrays at each position and returns the result.

    0 讨论(0)
  • 2020-12-16 21:50

    I'm away from my python at the moment, but does this one work?

    array( [ [ i*j for j in xrange(5)] for i in xrange(5)] )
    
    0 讨论(0)
  • 2020-12-16 21:51

    A generic solution would be to use np.fromfunction()

    From the doc:

    numpy.fromfunction(function, shape, **kwargs)

    Construct an array by executing a function over each coordinate. The resulting array therefore has a value fn(x, y, z) at coordinate (x, y, z).

    The below line should provide the required matrix.

    numpy.fromfunction(lambda i, j: i*j, (5,5))

    Output:

    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.]])
    

    The first parameter to the function is a callable which is executed for each of the coordinates. If foo is a function that you pass as the first argument, foo(i,j) will be the value at (i,j). This holds for higher dimensions too. The shape of the coordinate array can be modified using the shape parameter.

    0 讨论(0)
提交回复
热议问题