我正在编写一个程序,假设能够导入更高维度的numpy数组,例如像数组a:
a = numpy.zeros([3,5,7,2])
此外,每个尺寸将对应于一些物理尺寸,例如,频率,距离......我还会导入包含这些尺寸信息的数组,例如:以上:
freq = [1,2,3]
time = [0,1,2,3,4,5,6]
distance = [0,0,0,4,1]
angle = [0,180]
显然,从这个例子和签名中可以看出,freq属于维度0,时间属于维度2,依此类推。但由于事先不知道,我可以采用像
这样的频率切片a_f1 = a[1,:,:,:]
因为我不知道频率被索引到哪个维度。
所以,我想要的是有一些方法来选择索引索引的维度;在一些Python的代码中就像
a_f1 = a.get_slice([0,], [[1],])
这假设从维度0返回索引为1的切片以及其他完整维度。
否则
a_p = a[0, 1:, ::2, :-1]
然后会对应像
这样的东西a_p = a.get_slice([0, 1, 2, 3], [[0,], [1,2,3,4], [0,2,4,6], [0,]])
答案 0 :(得分:1)
您可以根据需要使用slice
对象轻松构建索引元组,然后使用它来索引数组。配方的基本原则是:
indices = {
0: # put here whatever you want to get on dimension 0,
1: # put here whatever you want to get on dimension 1,
# leave out whatever dimensions you want to get all of
}
ix = [indices.get(dim, slice(None)) for dim in range(arr.ndim)]
arr[ix]
这里我用字典完成了,因为我认为这样可以更容易地看出哪个维度与哪个索引器有关。
所以使用您的示例数据:
x = np.zeros([3,5,7,2])
我们这样做:
indices = {0: 1}
ix = [indices.get(dim, slice(None)) for dim in range(x.ndim)]
>>> x[ix].shape
(5L, 7L, 2L)
因为你的数组都是零,我只是显示结果的形状以表明它是我们想要的。 (即使它不是全零,也很难以文本形式读取3D数组。)
对于你的第二个例子:
indices = {
0: 0,
1: slice(1, None),
2: slice(None, None, 2),
3: slice(None, -1)
}
ix = [indices.get(dim, slice(None)) for dim in range(x.ndim)]
>>> x[ix].shape
(4L, 4L, 1L)
您可以看到形状与a_p
示例中的值数相对应。需要注意的一点是,第一个维度消失了,因为您只为该索引指定了一个值。最后一个维度仍然存在,但长度为1,因为您指定了恰好只获得一个元素的切片。 (这与some_list[0]
为您提供单一值的原因相同,但some_list[:1]
为您提供了单元素列表。)
答案 1 :(得分:0)
您可以使用advanced indexing来实现此目标。
每个维度的索引需要适当调整,以便索引在数组中正确广播。例如,三维数组的第一维的索引需要被整形(x, 1, 1)
,以便它将在第一维上广播。三维数组的第二维索引需要整形(1, y, 1)
,以便在第二维上进行广播。
import numpy as np
a = np.zeros([3,5,7,2])
b = a[0, 1:, ::2, :-1]
indices = [[0,], [1,2,3,4], [0,2,4,6], [0,]]
def get_aslice(a, indices):
n_dim_ = len(indices)
index_array = [np.array(thing) for thing in indices]
idx = []
# reshape the arrays by adding single-dimensional entries
# based on the position in the index array
for d, thing in enumerate(index_array):
shape = [1] * n_dim_
shape[d] = thing.shape[0]
#print(d, shape)
idx.append(thing.reshape(shape))
c = a[idx]
# to remove leading single-dimensional entries from the shape
#while c.shape[0] == 1:
# c = np.squeeze(c, 0)
# To remove all single-dimensional entries from the shape
#c = np.squeeze(c).shape
return c
对于a
作为输入,它返回一个形状为(1,4,4,1)的数组,a_p
示例的形状为(4,4,1)。如果需要删除额外的维度,请取消注释函数中的np.squeeze行。
现在我觉得很傻。在阅读文档较慢时,我注意到numpy有一个索引例程可以执行您想要的操作 - numpy.ix_
>>> a = numpy.zeros([3,5,7,2])
>>> indices = [[0,], [1,2,3,4], [0,2,4,6], [0,]]
>>> index_arrays = np.ix_(*indices)
>>> a_p = a[index_arrays]
>>> a_p.shape
(1, 4, 4, 1)
>>> a_p = np.squeeze(a_p)
>>> a_p.shape
(4, 4)
>>>