使用元素作为索引的函数创建一个numpy矩阵

时间:2011-06-06 15:57:35

标签: python matrix numpy

如何创建一个numpy矩阵,其元素是其索引的函数? 例如,乘法表:a[i,j] = i*j

Un-numpy和un-pythonic将创建一个零数组然后循环。

毫无疑问,有一种更好的方法可以做到这一点,没有循环。

然而,更好的方法是直接创建矩阵。

5 个答案:

答案 0 :(得分:8)

这是一种方法:

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

为了进一步说明,numpy.indices((5, 5))生成两个包含5x5数组的x和y索引的数组,如下所示:

>>> 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将每个位置的两个数组的值相乘并返回结果。

答案 1 :(得分:4)

用于乘法

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

一般

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)

基本上您通过np.ufunc创建np.frompyfunc,然后使用索引创建outer

修改

不同解决方案之间的速度比较。

小矩阵:

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

更大的矩阵:

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

答案 2 :(得分:3)

此刻我离开了我的python,但是这个有用吗?

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

答案 3 :(得分:3)

通用解决方案是使用np.fromfunction()

来自文档:

  

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

     

通过在每个坐标上执行函数来构造数组。的   因此,结果数组的坐标(x,y,   z)。

下面的行应提供所需的矩阵。

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

输出:

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

该函数的第一个参数是可调用的,可为每个坐标执行。如果foo是您作为第一个参数传递的函数,则foo(i,j)将是(i,j)的值。这也适用于更高的尺寸。可以使用shape参数修改坐标数组的形状。

答案 4 :(得分:2)

只是想补充一点,@ Senderle的响应可以针对任何函数和维度进行推广:

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

然后,您可以将a[i,j,k] = i*j*k计算为

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

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

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