构建一个包含冒号的元组,用于索引numpy数组

时间:2016-09-13 16:00:01

标签: python arrays numpy

我已经创建了一个用于处理特定类型的多维数据的类。该类有三个属性:包含轴名称的列表( self.axisNames );包含沿每个轴的参数值的字典( self.axes ; keyd使用axisNames中的条目);和包含数据的numpy数组,每个轴都有一个维度( self.intensityArr )。

该类还具有根据特定情况需要动态添加新轴的功能,这使得为intensityArr编制索引是一个棘手的主张。为了使索引更好,我开始编写一个函数来构建我需要的索引:

内部课程:

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'子句中添加:(或等效的)我用来索引intensityArr的元组?这可能是解决问题的不好方法吗?

2 个答案:

答案 0 :(得分:2)

在内部索引[]中,:被翻译为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(start, stop, step),启动和停止是可选的。与np.arangerange相同。 None等同于:表达式中未指定的值。

np.lib.index_tricks.py中的一个小型自定义类将:符号转换为切片:

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))

答案 1 :(得分:0)

要添加到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同样完成。您可以将np.s_[10:15]指定为slice(10, 15),将np.s_[:]指定为slice(None),如hpaulj所说。