我有一个数组 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行。
>>> 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]])
它沿着第一个维度工作,即行。
或者,可以使用广播:
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
会用零填充每隔一列。(np.arange(x.size)%2)*(x + np.array([-1,0,1])[:,None])
解释 -
np.arange(x.size)%2)
给我们交替的 0s
和 1s
。x + np.array([-1,0,1])[:,None])
以向量化的方式得到求和结果。步骤-1
中创建的交替的 1s
和 0s
来设置或不设置步骤-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]])
不使用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]]
就我个人而言,我会有不同的看法。你并不是将 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))
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]])
[[-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 |
y[:][::2]=0
不行呢?我最初尝试了一下,认为它的功能与y[:,::2]=0
相同。 - A By[:]
相当于y
,因为它索引了数组的全部内容。 因此,y[:][::2]
等同于y[::2]
,它是每隔一个“行”进行索引,而不是每隔一个“列”。 - ali_m