替换条件取决于数组中位置的python数组中的元素

时间:2018-09-10 19:52:40

标签: python

所以我想知道一种执行此计算的Python方式。我有一个全零的2D numpy数组。现在,根据坐标,我想在其中填充一些值。具体来说,我们有2个整数(a,b),然后在数组中用max(abs(index1-a), abs(index2-b))填充每个位置。

我正在想办法在一行中解决此问题,例如,如果我们想将所有负元素替换为0,那么:

array[array<0] = 0

有关如何单行解决问题的任何提示?我不是在寻找单行循环或lambda表达式。

2 个答案:

答案 0 :(得分:1)

使用np.indices + np.maximum

a, b = 3, 5
i, j = np.indices((10, 7))
np.maximum(np.abs(i - a), np.abs(j - b)))

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

np.indices将行和列索引作为2D矩阵返回;无需重塑。

答案 1 :(得分:0)

我们可以使用以下方法设计

a = 3  # sample a
b = 5  # sample b
arr = np.zeros((10, 7))  # sample zeros
m, n = arr.shape
arr[:,:] = np.maximum(np.arange(m).reshape(-1,1) - a, np.arange(n) - b)

但是,如果您不需要修改矩阵本身,我们可以简单地构造一个新矩阵(使用arr = np.maximum(..))。

对于具有a = 3b = 5的10×7矩阵,我们得到:

>>> arr
array([[-3., -3., -3., -2., -1.,  0.,  1.],
       [-2., -2., -2., -2., -1.,  0.,  1.],
       [-1., -1., -1., -1., -1.,  0.,  1.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.],
       [ 1.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.,  4.,  4.,  4.],
       [ 5.,  5.,  5.,  5.,  5.,  5.,  5.],
       [ 6.,  6.,  6.,  6.,  6.,  6.,  6.]])

编辑:如果要绝对值 np.abs(..)

arr[:,:] = np.maximum(np.abs(np.arange(m).reshape(-1,1) - a), np.abs(np.arange(n) - b))

那么结果是:

>>> arr
array([[5, 4, 3, 3, 3, 3, 3],
       [5, 4, 3, 2, 2, 2, 2],
       [5, 4, 3, 2, 1, 1, 1],
       [5, 4, 3, 2, 1, 0, 1],
       [5, 4, 3, 2, 1, 1, 1],
       [5, 4, 3, 2, 2, 2, 2],
       [5, 4, 3, 3, 3, 3, 3],
       [5, 4, 4, 4, 4, 4, 4],
       [5, 5, 5, 5, 5, 5, 5],
       [6, 6, 6, 6, 6, 6, 6]])

性能

我们定义了两个函数fg

>>> def f():
...   a, b = 3, 5
...   m, n = 10, 7
...   arr = np.zeros((m, n))
...   arr[:,:] = np.maximum(np.arange(m).reshape(-1,1) - a, np.arange(n) - b)
...
>>> def g():
...   a, b = 3, 5
...   m, n = 10, 7
...   arr = np.zeros((m, n))
...   i, j = np.indices((m, n))
...   arr[:,:] = np.maximum(np.abs(i - a), np.abs(j - b))

然后我们同时运行两个函数1'000'000次:

>>> timeit(f, number=1000000)
7.471106000011787
>>> timeit(g, number=1000000)
18.07209299999522

对于1000×700的矩阵,我们也将其运行了1000次:

>>> timeit(f, number=1000)
2.5362389999936568
>>> timeit(g, number=1000)
43.055561000001035

我对这种“性能差距”的假设是np.indices()创建了一个2×m×n的矩阵,因此分配了相似数量的内存。通过构造两个1d数组,我们在中间矩阵中采用线性时间,并利用广播来计算最终矩阵的元素。