我创建了一个类来处理特定类型的多维数据。这个类有三个属性:一个包含坐标轴名称的列表(self.axisNames);包含沿每个轴的参数值的字典(self.axes;(使用axisNames中的条目);以及包含数据的numpy数组,每个轴具有一个维度(self. intensityr )。
类还具有根据特定情况的需要动态添加新轴的函数,这使得索引intensityr成为一个棘手的命题。为了使索引更好,我已经开始编写一个函数来构建我需要的索引:
内部类:
def indexIntensityArr(self,indexSpec):
# indexSpec is a dictionary containing axisName:indexVal entries (indexVal is an int)
# I want the function to return a tuple for use in indexing (see below def)
indexList = []
for axis in self.axisNames:
if axis in indexSpec:
indexList.append(indexSpec[axis])
else:
# <do something to add : to index list (tuple)>
return tuple(indexList)
课外
:
# ... create an instance of my class called myBlob with 4 dimensions ...
mySpec = {'axis1':10,'axis3':7}
mySlicedArr = myBlob.intensityArr[myBlob.indexIntensityArr(mySpec)]
我期望上面的结果是mySlicedArr是一个二维数组。
我需要在"else"子句中放入什么才能在我用来索引intensityr的元组中获得:(或同等物)?这是不是一个不好的解决问题的方法?
在索引[]
时,将:
转换为slice
,并将整个内容作为元组传递给__getitem__
indexList = []
for axis in self.axisNames:
if axis in indexSpec:
indexList.append(indexSpec[axis])
else:
indexList.append(slice(None))
有几个numpy
函数使用了这样的索引技巧——即建立一个索引值和切片的元组。或者,如果他们需要改变它,他们将从一个可以变化的列表开始,并在使用之前将其转换为元组。(如np.apply_along_axis
)
是的,slice的完整规格是slice(start, stop, step)
,启动和停止是可选的。与np.arange
或range
相同。None
相当于:
表达式中未指定的值。
np.lib.index_tricks.py
中的一个小自定义类将:符号转换为slices:
In [61]: np.s_[:,:1,0:,::3]
Out[61]:
(slice(None, None, None),
slice(None, 1, None),
slice(0, None, None),
slice(None, None, 3))
要添加到hpaulj的答案中,您可以非常简单地扩展您的设置,通过使用np.s_
使其更加通用。与slice
相比,使用它的优点是可以更容易、更透明地使用numpy
的切片语法。例如:
mySpec = {'axis1': np.s_[10:15], 'axis3': np.s_[7:8]}
mySlicedArr = myBlob.intensityArr[myBlob.indexIntensityArr(mySpec)]
(额外信息:np.s_[7:8]
只检索第7列,但它保留了维度,即你的切片数组仍然是4D与1的形状在该维度:非常有用的广播)。
如果你想在你的函数定义中使用相同的语法:
indexList = []
for axis in self.axisNames:
if axis in indexSpec:
indexList.append(indexSpec[axis])
else:
indexList.append(np.s_[:])
return tuple(indexList)
所有这些都可以用slice
做得很好。如hpaulj所示,您可以将np.s_[10:15]
指定为slice(10, 15)
,将np.s_[:]
指定为slice(None)
。