首页 > 技术文章 > matrix根据argsort取值的内容分析

gwzz 2020-08-18 19:24 原文

numpy主要有两大类:narray和matrix(或简写mat),他们都有排序方法sort()和argsort()

这两个函数,默认都是按照纵轴切分数据,然后在各自切分的数据上进行从小到大排序。

 

sort()

会改变原有变量的数据存放,若是不想改变的话,可以使用copy(),即narray.copy()和matrix.copy(),复制一份新的数据到变量上。举例:

        rawDataMat = mat([
            [1,  2,  10],
            [12, 5,  12],
            [21, 3,  1],
            [4,  8,  2], 
            [7,  10, 13], 
            [6,  9,  5]])

        print('rawDataMat\n{0}'.format(rawDataMat))

        sortIndexData = rawDataMat.sort(0)
        print('sortData\n{0}'.format(rawDataMat))

---------------------------------------------------------------------
返回值:
rawDataMat
[[ 1  2 10]
 [12  5 12]
 [21  3  1]
 [ 4  8  2]
 [ 7 10 13]
 [ 6  9  5]]
sortData
[[ 1  2  1]
 [ 4  3  2]
 [ 6  5  5]
 [ 7  8 10]
 [12  9 12]
 [21 10 13]]

 

sort(0):在横轴上切分,对每个切分列进行从小到大排列;

若是sort():在纵轴上切分,对每个切分行(即每一个行)从小到大排列。

默认是行数据,从小到大排列

 

argsort()

不会改变原来变量的数据存放,而是获得原来变量的数据索引值,可以对array和matrix进行处理。

argsort(0):对每列取从小到大排列的对应索引值,

argsort():对每行取从小到大排列的对应索引值,

默认是行数据的从小到大排列的索引值,示例如下:

        rawDataMat = mat([
            [1,  2,  10],
            [12, 5,  12],
            [21, 3,  1],
            [4,  8,  2], 
            [7,  10, 13], 
            [6,  9,  5]])
        print('rawDataMat\n{0}'.format(rawDataMat))

        # 0-按横轴,切分
        sortIndex0 = rawDataMat.argsort(0)
        print('sortIndex0\n{0}'.format(sortIndex0))

        # 默认按列轴切分,在切分方向上从小到大排列,给出indices
        sortIndex = rawDataMat.argsort()
        print('sortIndex\n{0}'.format(sortIndex))
--------------------------------------------------------- 结果: rawDataMat [[ 1 2 10] [12 5 12] [21 3 1] [ 4 8 2] [ 7 10 13] [ 6 9 5]] sortIndex0 [[0 0 2] [3 2 3] [5 1 5] [4 3 0] [1 5 1] [2 4 4]] sortIndex [[0 1 2] [1 0 2] [2 1 0] [2 0 1] [0 1 2] [2 0 1]]

 

若原矩阵按索引值来获取排序值的话,则从小到大的数据以对角线上的值为起点,按左到右顺序取列数据。示例:

       rawDataMat = mat([
            [1,  2,  10],
            [12, 5,  12],
            [21, 3,  1],
            [4,  8,  2], 
            [7,  10, 13], 
            [6,  9,  5]])
        print('rawDataMat\n{0}'.format(rawDataMat))

        # 0-按横轴,切分
        sortIndex0 = rawDataMat.argsort(0)
        print('sortIndex0\n{0}'.format(sortIndex0))

        sortDataMat = rawDataMat[sortIndex0]
        print('sortDataMat\n{0}'.format(sortDataMat))
------------------------------------- 结果为: rawDataMat [[ 1 2 10] [12 5 12] [21 3 1] [ 4 8 2] [ 7 10 13] [ 6 9 5]] sortIndex0 [[0 0 2] [3 2 3] [5 1 5] [4 3 0] [1 5 1] [2 4 4]] sortDataMat [[[ 1 2 10] [ 1 2 10] [21 3 1]] [[ 4 8 2] [21 3 1] [ 4 8 2]] [[ 6 9 5] [12 5 12] [ 6 9 5]] [[ 7 10 13] [ 4 8 2] [ 1 2 10]] [[12 5 12] [ 6 9 5] [12 5 12]] [[21 3 1] [ 7 10 13] [ 7 10 13]]]

 

此时sortDataMat会增加维度,此处为(6,3,3)有没有什么好的方法,可以降维呢?方法如下:

        sortColumnMat = sortDataMat[:, 0, 0]
        # sortColumnMat = sortDataMat[:, 1, 1]
        # sortColumnMat = sortDataMat[:, 2, 2]
        print('sortColumnMat\n{0}'.format(sortColumnMat))
        print(sortColumnMat.shape)
------------------------------------
结果:
sortColumnMat
[[ 1]
 [ 4]
 [ 6]
 [ 7]
 [12]
 [21]]
(6, 1)

 

以上,可以得到排序的各个列,我们还可以优化代码,示例如下:

        featCount = sortDataMat.shape[-1]
        for i in range(featCount):
            sortColumnMat = sortDataMat[:, i, i]
            print('sortColumnMat第{0}列,内容为:\n{1}'.format(i, sortColumnMat))
---------------------------------------------
结果:
sortColumnMat第0列,内容为:
[[ 1]
 [ 4]
 [ 6]
 [ 7]
 [12]
 [21]]
sortColumnMat第1列,内容为:
[[ 2]
 [ 3]
 [ 5]
 [ 8]
 [ 9]
 [10]]
sortColumnMat第2列,内容为:
[[ 1]
 [ 2]
 [ 5]
 [10]
 [12]
 [13]]

 

到此,我们可以根据argsort(0),正常获得各个列的从小到大的排序数据。我们还可以利用flatten来减少矩阵的行,实现降维,然后将矩阵转化为数据,示例:

        featCount = sortDataMat.shape[-1]
        for i in range(featCount):
            sortColumnMat = sortDataMat[:, i, i]
            # print('sortColumnMat第{0}列,内容为:\n{1}'.format(i, sortColumnMat))
            sortDataList = sortColumnMat.flatten().A[0]
            print('sortDataList,第{0}列对应的数组数据为:{1},类型为:{2}'.format(i, sortDataList, type(sortDataList)))
--------------------------------
结果:

sortDataList,第0列对应的数组数据为:[ 1 4 6 7 12 21], 类型为:<class 'numpy.ndarray'>
sortDataList,第1列对应的数组数据为:[ 2 3 5 8 9 10], 类型为:<class 'numpy.ndarray'>
sortDataList,第2列对应的数组数据为:[ 1 2 5 10 12 13], 类型为:<class 'numpy.ndarray'>

 

利用flatten()降维到一行数据,然后利用A转化为数组,[0]表示取里面的第一个数据,该数据类型为numpy的数组ndarray

推荐阅读