获得2D阵列的中位数或平均值之前的numpy REJECTION

时间:2014-11-13 10:04:31

标签: python arrays numpy

我正在尝试编写一些函数来处理FIT/FITS(这些基本上是图像)文件。这些文件在天文学中很常见。 在我的情况下,有一堆校准图像,想要获得所有图像的平均值或中位数。

所以基本上如果我的图像(数组)是:

ar1 = [[021, 654], [087, 065]]
ar2 = [[009, 097], [879, 009]]
ar1 = [[945, 008], [002, 007]]
中值方法的

resoult图像(数组)将是:

armed = [[021, 097],[087, 009]]

和平均值相同

我找到了:

mainArray = [ar1, ar2,  ar3]
armed = numpy.median(mainArray, axis=0)
arave = numpy.average(mainArray, axis=0)
arsum = numpy.add(mainArray, axis=0)
arsub = numpy.subtract(mainArray, axis=0)

这些都很好用。但我也想拒绝。例如,在平均数组之前,我想使用min-max rejection。

有四种类型的组合和三种类型的拒绝。

组合类型:总和,减法,中位数和平均值。 拒绝类型:none,min-max,sigma Clip。

如何在组合数组之前拒绝?

我刚写了一个班来做min-max拒绝。然而,拒绝最小10倍(2048x2048)阵列需要花费很长时间。实际上,在阿瑞是(10,2048,2048)形状,但作为回报,我得到(2048年,2048年,8年)。 8表示min-max被拒绝。但反过来。 :(

def minmaxrej(self, inArray, verb=False):
    """
    Returns all images minmax rejected.

    @param inArray: All arrays to reject minmax. It'll return a reverced array.
    @type inArray: numpy.array
    @param verb: Get information while operation (Optional, False by default).
    @type verb: boolean
    @return: numpy.array
    """
    if type(inArray) == numpy.ndarray:
        if len(inArray.shape) == 3:
            if inArray.shape[0] > 2:
                poi = []
                ln = []
                lst = []

                for i in xrange(inArray.shape[1]):
                    for u in xrange(inArray.shape[2]):
                        for k in xrange(inArray.shape[0]):
                            poi.append(inArray[k][i][u])
                        poi = numpy.sort(poi)[1:-1]
                        ln.append(poi)
                        poi = []
                    lst.append(ln)
                    ln = []
                lst = numpy.asarray(lst)
                if verb:
                    print "'minmaxrej' done."
                return lst

            else:
                if verb:
                    print "Min-Max rejection requires at least 3 arrays. Got %s." %(inArray.shape[0])
        else:
            if verb:
                print "Wrong array shape. Expected array type: %s" %(inArray.shape)
    else:
        if verb:
            print "Unexpected input type for input arrays.\nArray expected.\nReceived %s" %(type(inArray))

在此之后,我可以获得此数组的中位数,平均值,平均值,总和等。但是花了太长时间。我需要更有效,更快捷的方法来做到这一点。

1 个答案:

答案 0 :(得分:0)

新:

import numpy as np
ar1 = [[21, 654], [87, 65]] # this is a nested list and becomes matrix-like if np.array(ar1) is called
ar2 = [[9, 97], [879, 9]]
ar3 = [[945, 8], [2, 7]]
all_arr = np.array([ar1,ar2,ar3]) # This is a list of 'matrices' / np.arrays with shape (m,n)
matrix = all_arr.reshape((3,4)).T # This is getting rid of the list so that we now have an array of shape (#arrs, #len(each arr))

我使用转置,以便每个图像(例如ar1)都是一列,每一行都是一个像素

Output:
array([[ 21,   9, 945],
       [654,  97,   8],
       [ 87, 879,   2],
       [ 65,   9,   7]])

然后,您可以定义您想要的任何过滤器

def is_min_or_max(X):
    return (X == np.max(X))|(X == np.min(X))

然后过滤我们的'矩阵'你可以将这个'过滤器'应用到每个行/像素上 map(is_min_or_max, matrix)。这会给你:

Output:
[array([False,  True,  True], dtype=bool),
 array([ True, False,  True], dtype=bool),
 array([False,  True,  True], dtype=bool),
 array([ True, False,  True], dtype=bool)]

如果我理解正确你想要丢弃图片(arr1),如果任何过滤器适用于该图像中的任何像素,这意味着 如果数组中的任何值为true,则丢弃图片。然后你得到你的矩阵:

matrix[:, np.invert(map(any, map(is_min_or_max, matrix)))]

Output: array([], shape=(4L, 0L), dtype=int32)

在这种情况下哪个是空的,因为每个图像都有一个排除因子。 如果它不是空的,那么您可以在您选择的轴(像素或图像)上使用np.mean()等功能,就像您已经完成的那样。


OLD:

在你的情况下,我可能会使用numpy矩阵,因为它们支持在任一轴上轻松切片和布尔过滤。

import numpy as np
import itertools

ar1 = [[21, 654], [87, 65]]
ar2 = [[9, 97], [879, 9]]
ar3 = [[945, 8], [2, 7]]

ar1 = list(itertools.chain.from_iterable(ar1))
ar2 = list(itertools.chain.from_iterable(ar2))
ar3 = list(itertools.chain.from_iterable(ar3))
mat = np.matrix([ar1,ar2,ar3])
armed = np.median(mat,0)
arave = np.mean(mat,0)

......等等。然后可以通过像

这样的切片对矩阵进行拒绝
mat[mat[:,0] < np.max(mat[:,0])]

为第一列。切片也可以是布尔矩阵,因此您可以组合所有列的条件

由于