NumPy数组:选择d维数组中的所有偶数元素

3
有没有一种高效且符合Python风格的方法,可以从一个d维数组中选择所有索引为偶数的元素,而不需要预先知道d?还有那些剩下的元素(即至少有一个奇数索引的元素)?
第一个问题的最小示例:
import numpy as np
a = np.array(range(27)).reshape((3,3,3))
a[::2,::2,::2] 
# -> array([[[ 0,  2],
#            [ 6,  8]],
#           [[18, 20],
#            [24, 26]]])

我找到的针对d维对象(d是变量)的唯一非pythonic方法 至少对于“所有偶数”部分,但对于“至少有一个奇数”的部分仍然无法理解。

d = 3
a = np.array(range(3**d)).reshape([3]*d)
b = a
for i in range(d):
    b = np.take(b, np.array(range(0,b.shape[i],2)), axis=i)

我问这个问题的原因是,我想逐步创建一个大小为(2**n+1, ..., 2**n+1)的大型d维对象,需要n步完成。每一步都从上一步中复制偶数索引元素,类似于:

for n in range(N):
    new_array = np.zeros([2**n+1]*d)
    new_array[all_even] = old_array
    new_array[at_least_one_odd] = #something else

感谢您提前提供的任何提示!

2个回答

3

我想你可以使用切片对象。

even = a[[slice(None, None, 2) for _ in range(a.ndim)]]
odd = a[[slice(1, None, 2) for _ in range(a.ndim)]]

谢谢您的回答,但不幸的是,当我尝试运行它时,我收到了一些警告和错误,其中最基本的一个是numpy没有“slice”模块...虽然@Divakar的答案已经满足了我的需求(至少对于第一个问题而言,我猜第二个问题没有令人满意的答案),您能否解释一下您的答案背后的原理,这可能对我有所帮助,以便我理解?谢谢! - Marco Spinaci
1
抱歉,切片对象是Python内置的。我更新了我的答案。我想这样更易读。 - miindlek
非常感谢,确实很好!我不知道有一个“切片”内置函数可以替换切片:符号,这确实很有用。只是为了澄清,问题的第二部分是要求具有至少一个奇数索引的元素,而不是所有奇数;在这个例子中,有27个元素,其中8个是偶数,我天真地希望有一种方法来获得其余的19个(它们必须被展平,因为它们失去了任何形状)。但是,我越想越觉得不合理,因此我完全满意第一部分,谢谢! - Marco Spinaci
根据一些快速的运行时测试,看起来相当高效!不错。 - Divakar

2

以下是使用np.ix_的方法 -

a[np.ix_(*[range(0,i,2) for i in a.shape])]

示例运行 -


In [813]: def even_idx(a):
     ...:     return a[np.ix_(*[range(0,i,2) for i in a.shape])]
     ...: 

In [814]: a = np.array(range(27)).reshape((3,3,3))

In [815]: np.allclose(a[::2,::2,::2], even_idx(a) )
Out[815]: True

In [816]: a = np.array(range(27*4)).reshape((3,3,3,4))

In [817]: np.allclose(a[::2,::2,::2,::2], even_idx(a) )
Out[817]: True

In [818]: a = np.array(range(27*4*5)).reshape((3,3,3,4,5))

In [819]: np.allclose(a[::2,::2,::2,::2,::2], even_idx(a) )
Out[819]: True

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