在二维数组中插入0

13

我有一个数组 x:

x = [0, -1, 0, 3]

我希望有y:

y = [[0, -2, 0, 2],
     [0, -1, 0, 3],
     [0,  0, 0, 4]]

第一行是x-1,第二行是x,第三行是x+1。所有偶数列索引都为零。

我正在做:

y=np.vstack(x-1, x, x+1)
y[0][::2] = 0
y[1][::2] = 0
y[2][::2] = 0

我在想,可能有一行代码可以代替这4行。

7个回答

10

两行概述

>>> x = np.array([0, -1, 0, 3])
>>> y = np.vstack((x-1, x, x+1))
>>> y[:,::2] = 0
>>> y
array([[ 0, -2,  0,  2],
       [ 0, -1,  0,  3],
       [ 0,  0,  0,  4]])

解释

y[:, ::2]

提供完整的第一维,即第二维中的所有行和每个其他条目,即列:

array([[-1, -1],
       [ 0,  0],
       [ 1,  1]])

这与以下不同:

y[:][::2]

因为这个过程需要分两步进行。第一步:

y[:]

给出整个数组的视图:

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

因此,第二步基本上是这样做:

y[::2]
array([[-1, -2, -1,  2],
       [ 1,  0,  1,  4]])

它沿着第一个维度工作,即行。


谢谢,那个可行,但是为什么 y[:][::2]=0 不行呢?我最初尝试了一下,认为它的功能与 y[:,::2]=0 相同。 - A B
@AB y[:] 相当于 y,因为它索引了数组的全部内容。 因此,y[:][::2] 等同于 y[::2],它是每隔一个“行”进行索引,而不是每隔一个“列”。 - ali_m

4

或者,可以使用广播

import numpy as np

x = np.array([0, -1, 0, 3])
delta = np.array([-1, 0, 1])
y = x + delta[:, None]
y[:, ::2] = 0

print(repr(y))
# array([[ 0, -2,  0,  2],
#        [ 0, -1,  0,  3],
#        [ 0,  0,  0,  4]])
  • delta 指定了每一行要添加 / 减去的数量。
  • 使用 None 进行索引会插入一个新的大小为 1 的维度。
  • delta[:, None].shape == (3, 1) 并且 x.shape == (4,),所以 x + delta[:, None] 的结果会被广播到一个 (3, 4) 数组中。
  • 最后,y[:, ::2] = 0 会用零填充每隔一列。

3
使用 NumPy的广播 作为一行代码 -
(np.arange(x.size)%2)*(x + np.array([-1,0,1])[:,None])

解释 -

  1. np.arange(x.size)%2) 给我们交替的 0s1s
  2. 使用广播和 x + np.array([-1,0,1])[:,None]) 以向量化的方式得到求和结果。
  3. 使用在 步骤-1 中创建的交替的 1s0s 来设置或不设置步骤-2中求和数组的列,从而产生最终输出。

样例运行 -

In [40]: x
Out[40]: array([ 0, -1,  0,  3])

In [41]: (np.arange(x.size)%2)*(x + np.array([-1,0,1])[:,None])
Out[41]: 
array([[ 0, -2,  0,  2],
       [ 0, -1,  0,  3],
       [ 0,  0,  0,  4]])

2

不使用numpy的一行代码:

x = [0, -1, 0, 3]
y = [ [(x[i] - j if i%2 else 0) for i in range(4)] for j in (1,0,-1)]

给出以下y

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

1

就我个人而言,我会有不同的看法。你并不是将 x 加上 1,而是加上 [0, 1, 0, 1]

x = np.array([0, -1, 0, 3])
d = np.resize([0, 1], len(x))
y = np.vstack((x-d, x, x+d))

1

NumPy中的一行代码:

>>> x = np.array([0, -1, 0, 3])
>>> y = np.vstack((x-1, x, x+1)) * np.resize([0, 1], len(x))
>>> y
array([[ 0, -2,  0,  2],
       [ 0, -1,  0,  3],
       [ 0,  0,  0,  4]])

0
一个简短的版本:[[-1],[0],[1]] *(x!= 0)+ x [[-1],[0],[1]] *(x!= 0) 是什么意思。
     |-1                                    |-1                   | 0 -1 0 -1 |
dot( |0  , [True False True False] ) = dot( |0  ,  [ 1 0 1 0] ) = | 0  0 0  0 |  = z
     |1                                     |1                    | 0  1 0  1 |

z + x 是:(广播)

| 0 -1 0 -1 |   | 0 -1 0 3 |    | 0 -2 0 2 |
| 0  0 0  0 | + | 0 -1 0 3 |  = | 0 -1 0 3 |
| 0  1 0  1 |   | 0 -1 0 3 |    | 0  0 0 4 |

1
单独的代码块不足以提供一个好的答案。请添加解释(为什么它解决了问题,哪里出了错误等等...) - Louis Barranqueiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接