在删除 axis0 的 I 索引的子元素的同时创建一个平铺的多维数组?
Creating a tiled multi-dimensional array while removing the sub element of the I'th index of axis0?
我试图平铺一个数组,其中每个索引都是多维的。
然后我从每个索引中删除第 i 个子元素。
例如,从这个数组开始:
>>> a = np.array([[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]])
>>> a = np.tile(a, (a.shape[0],1,1))
>>> print a
array([[[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]],
[[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]],
[[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]]])
期望的输出:
b = np.array([[[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]],
[[ 1. , 7. , 0. ],
[ 3. , 7. , 0. ]],
[[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ]]])
我想知道是否有更有效的方法来生成此输出而不必先创建一个大数组然后从中删除?
[更新]
此排列背后的意图是尝试矢量化而不是使用 python for 循环。 Divakar 提供的答案对完成这项任务有很大帮助。我还想 link 到 ,它显示了这个排列的逆向,并且在我完成后重新排列所有值以求和所有值很有用。
此外,我正在尝试使用 Tensorflow 在张量上使用相同的排列技术(请参阅 )
方法 #1 : 这是一种方法,它创建一个二维索引数组,以便在每一行的每个 i-th
位置跳过这些索引,然后将其用于索引到输入数组的第一个轴 -
def approach1(a):
n = a.shape[0]
c = np.nonzero(~np.eye(n,dtype=bool))[1].reshape(n,n-1) # dim0 indices
return a[c]
样本运行-
In [272]: a
Out[272]:
array([[56, 95],
[31, 73],
[76, 61]])
In [273]: approach1(a)
Out[273]:
array([[[31, 73],
[76, 61]],
[[56, 95],
[76, 61]],
[[56, 95],
[31, 73]]])
方法 #2 : 这是另一种使用 np.broadcast_to
的方法,它创建输入数组的扩展视图,然后将其屏蔽以获得所需的输出 -
def approach2(a):
n = a.shape[0]
mask = ~np.eye(n,dtype=bool)
return np.broadcast_to(a, (n, n, a.shape[-1]))[mask].reshape(n,n-1,-1)
运行时测试
In [258]: a = np.random.randint(11,99,(200,3))
In [259]: np.allclose(approach1(a), approach2(a))
Out[259]: True
In [260]: %timeit approach1(a)
1000 loops, best of 3: 1.43 ms per loop
In [261]: %timeit approach2(a)
1000 loops, best of 3: 1.56 ms per loop
我试图平铺一个数组,其中每个索引都是多维的。 然后我从每个索引中删除第 i 个子元素。
例如,从这个数组开始:
>>> a = np.array([[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]])
>>> a = np.tile(a, (a.shape[0],1,1))
>>> print a
array([[[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]],
[[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]],
[[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]]])
期望的输出:
b = np.array([[[ 2. , 7. , 0. ],
[ 3. , 7. , 0. ]],
[[ 1. , 7. , 0. ],
[ 3. , 7. , 0. ]],
[[ 1. , 7. , 0. ],
[ 2. , 7. , 0. ]]])
我想知道是否有更有效的方法来生成此输出而不必先创建一个大数组然后从中删除?
[更新]
此排列背后的意图是尝试矢量化而不是使用 python for 循环。 Divakar 提供的答案对完成这项任务有很大帮助。我还想 link 到
此外,我正在尝试使用 Tensorflow 在张量上使用相同的排列技术(请参阅
方法 #1 : 这是一种方法,它创建一个二维索引数组,以便在每一行的每个 i-th
位置跳过这些索引,然后将其用于索引到输入数组的第一个轴 -
def approach1(a):
n = a.shape[0]
c = np.nonzero(~np.eye(n,dtype=bool))[1].reshape(n,n-1) # dim0 indices
return a[c]
样本运行-
In [272]: a
Out[272]:
array([[56, 95],
[31, 73],
[76, 61]])
In [273]: approach1(a)
Out[273]:
array([[[31, 73],
[76, 61]],
[[56, 95],
[76, 61]],
[[56, 95],
[31, 73]]])
方法 #2 : 这是另一种使用 np.broadcast_to
的方法,它创建输入数组的扩展视图,然后将其屏蔽以获得所需的输出 -
def approach2(a):
n = a.shape[0]
mask = ~np.eye(n,dtype=bool)
return np.broadcast_to(a, (n, n, a.shape[-1]))[mask].reshape(n,n-1,-1)
运行时测试
In [258]: a = np.random.randint(11,99,(200,3))
In [259]: np.allclose(approach1(a), approach2(a))
Out[259]: True
In [260]: %timeit approach1(a)
1000 loops, best of 3: 1.43 ms per loop
In [261]: %timeit approach2(a)
1000 loops, best of 3: 1.56 ms per loop