关于python:如果事先不知道维度和选择标准的数量,将列表传递给numpy.ix_,或者如何切割多维数组?

Passing a list to numpy.ix_, or how to slice a multidimensional array, when number of dimensions and selection criteria are not known beforehand?

我想用numpy分割多维数组。假设我的数组是一个5*5*5的数组,我在理论上考虑到的切片可以使用numpy.ix_uuuu完成:

1
2
3
4
    s0 = [0,1,2]
    s1 = [1,2,3]
    s2 = [1,2,3]
    b = a[numpy.ix_(s0,s1,s2)]

问题是数组的维数,以及我需要在程序中沿不同维数分割数组的方式发生了变化(例如数组"a"可能是2,3,4,…)。尺寸,和S0,S1,…也可以更改),所以上面的代码不会按我喜欢的方式工作,除非我可以将列表/元组传递给numpy.ix,如下所示:

1
2
3
4
5
6
7
    N = 3
    M = 3
    s = [np.ones(M).astype(int) for i in range(N)]
    s[0] = [0,1,2]
    s[1] = [1,2,3]
    s[2] = [1,2,3]        
    b = a[numpy.ix_(s)]

不幸的是,这不起作用,因为ix只接受一维对象(?).什么是最好的解决方法?如何干净地实现ix_uu我自己(或者是否有更简单的方法来做到这一点?)?


使用*参数解包运算符:

1
b = a[numpy.ix_(*s)]

等于

1
b = a[numpy.ix_(s[0], s[1], ..., s[n])]

例如,

1
2
3
4
5
6
7
8
9
10
11
import numpy as np

N = 3
M = 3
a = np.arange((M+1)**N).reshape([M+1]*N)
s = [np.ones(M).astype(int) for i in range(N)]
s[0] = [0,1,2]
s[1] = [1,2,3]
s[2] = [1,2,3]        
b = a[np.ix_(*s)]
print(b)

印刷品

1
2
3
4
5
6
7
8
9
10
11
[[[ 5  6  7]
  [ 9 10 11]
  [13 14 15]]

 [[21 22 23]
  [25 26 27]
  [29 30 31]]

 [[37 38 39]
  [41 42 43]
  [45 46 47]]]