如何确定在numpy中包含“ None”和“:”的切片?

问题描述

我正在替代itertools.product作为练习,而我的方法是使用np.broadcast

import numpy as np
x = np.array([4,3,1])
y = np.array([2,4,0])
z = np.array([0,1,2])
ix = np.broadcast(x[:,None,None],y[None,:,z[None,:])
print(*ix)

这次工作正常,但是如果我愿意,如何自动创建所有这些“按眼睛排列”的新轴,比如说7个尺寸:

[:,None]
[None,:]

我期望np.ix_之类的东西允许在分配这些切片时使用所有这些None:

解决方法

每个索引都是一个n元素元组。每个元组的 diagonal 元素,即第i个元组的第i个元素,是一个slice对象。具体来说,:代表slice(None)。 (通常,x:y:z是对象slice(x,y,z),所有缺少的元素都是None,尽管必须至少提供一个参数)。

arguments = [(None,)*i + (slice(None),) + (None,)*(6-i) for i in range(7)]
# E.g.,i == 0 -> () + (slice(None),None,None)
#              == (slice(None),None)
ix = np.broadcast(*(x[arg] for arg in arguments))
,

方法1

可以使用相同的眼睛排列来重塑所有参与的数组-

A = [x,z] # all arrays
s = 1-2*np.eye(len(A),dtype=int)
out = [a.reshape(i) for i,a in zip(s,A)]

这是使用s进行整形的技巧部分:

In [53]: s
Out[53]: 
array([[-1,1,1],# reshape to keep all axes singleton except first
       [ 1,-1,#                                       .. second 
       [ 1,-1]]) #                                      ... third

因此,考虑将[-1,1]整形以使除第一个轴以外的所有轴保持单身。与[:,None]相同,依此类推。

方法2

使用相同的眼睛布置获取索引器-

idx = np.where(np.eye(len(A)),Ellipsis,None)
out = [a[tuple(i)] for a,i in zip(A,idx)]

索引器是:

In [77]: idx
Out[77]: 
array([[Ellipsis,None],[None,Ellipsis]],dtype=object)