以向量化方式创建给定大小的NumPy矩阵

时间:2019-05-28 21:06:01

标签: python numpy vectorization

是否有内置的NumPy函数或任何 vectorized 方法生成值为n> 1的以下2D NumPy矩阵?让我举例说明n等于2、3和4的 所需矩阵

一种方法是在下三角部分构造1的矩阵,然后简单地乘以向量np.arange(1, n+1)。还有其他选择吗?

import numpy as np

对于n = 2

n = 2
arr = np.array([[1, 0], [2, 2]])

# array([[1, 0],
#        [2, 2]])

对于n = 3

n = 3
arr = np.array([[1, 0, 0], [2, 2, 0], [3, 3, 3]])

# array([[1, 0, 0],
#        [2, 2, 0],
#        [3, 3, 3]])

对于n = 4

n = 4
arr = np.array([[1, 0, 0, 0], [2, 2, 0, 0], [3, 3, 3, 0], [4, 4, 4, 4]])

# array([[1, 0, 0, 0],
#        [2, 2, 0, 0],
#        [3, 3, 3, 0],
#        [4, 4, 4, 4]])

我的尝试(例如n = 4的示例)使用嵌套的for循环。它适用于n> 1:

的任何值
import numpy as np

n = 4
arr = np.zeros((n, n))

for i in range(n):
    for j in range(0, i+1):
        arr[i][j] = i+1 

# array([[1., 0., 0., 0.],
#        [2., 2., 0., 0.],
#        [3., 3., 3., 0.],
#        [4., 4., 4., 4.]])    

3 个答案:

答案 0 :(得分:5)

您可以使用np.trilnp.broadcast_to创建初始的arange变体。

import numpy as np

n = 4
np.tril(np.broadcast_to(np.arange(1, n+1)[:, None], (n, n)))

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

答案 1 :(得分:4)

我们可以使用范围数组乘以下三角遮罩-

import itertools

result = itertools.starmap(call, list_2)

考虑到算术导向的性质,它很容易移植到In [44]: n = 5 In [45]: np.arange(1,n+1)[:,None]*np.tri(n,dtype=bool) Out[45]: array([[1, 0, 0, 0, 0], [2, 2, 0, 0, 0], [3, 3, 3, 0, 0], [4, 4, 4, 4, 0], [5, 5, 5, 5, 5]]) 中以利用多核处理大数据-

numexpr

基准化

在此处包括所有已发布的解决方案。

基准化脚本-

import numexpr as ne

ne.evaluate('A*B',{'A':np.arange(1,n+1)[:,None],'B':np.tri(n,dtype=bool)})

输出-

enter image description here

因此,在import numpy as np import perfplot import numexpr as ne def numexpr_range_broadcast(n): return ne.evaluate('A*B',{'A':np.arange(1,n+1)[:,None],'B':np.tri(n,dtype=bool)}) def where_method(n): x = np.arange(1,n+1) return np.where(x[:,None]>=x,x[:,None],0) perfplot.show( setup=lambda n: n, kernels=[ lambda n: where_method(n), lambda n: np.tril(np.broadcast_to(np.arange(1, n+1)[:, None], (n, n))), lambda n: np.arange(1,n+1)[:,None]*np.tri(n,dtype=bool), lambda n: numexpr_range_broadcast(n), ], labels=['where','tril_broadacast','range_broadcast','numexpr_range_broadcast'], n_range=[10, 20, 50, 80, 100, 200, 500, 800, 1000, 2000, 5000], xlabel='n', logx=True, logy=True, ) 之前的较低n's上,基于100的人赢了,而在较大的np.where上,n's发光。

答案 2 :(得分:2)

这是使用np.where和广播的解决方案:

x = np.arange(1,n+1)
np.where(x[:,None]>=x,x[:,None],0)
# array([[1, 0, 0, 0],
#        [2, 2, 0, 0],
#        [3, 3, 3, 0],
#        [4, 4, 4, 4]])