重新组织3D Numpy数组

时间:2018-11-21 22:59:34

标签: python numpy matplotlib

我已经尝试和搜索了几天,我已经接近了,但需要您的帮助。

我在python中有一个3d数组,

shape(files)
>> (31,2049,2)

对应于31个输入文件,其中2列数据具有2048行和一个标题。

我想基于每个文件中的标头对数组进行排序。

我尝试关注NumPy: sorting 3D array but keeping 2nd dimension assigned to first,但我感到非常困惑。

首先,我尝试设置以获取argsort的标头,我认为我可以这样做

sortval=files[:][0][0]

但这不起作用。

然后我只是做了一个for循环来迭代并获取我的标题

for i in xrange(shape(files)[0]:
    sortval.append([i][0][0])

然后

sortedIdx = np.argsort(sortval)

这行得通,但是我不明白最后一行发生了什么。

files = files[np.arange(len(deck))[:,np.newaxis],sortedIdx]

我们将不胜感激。

2 个答案:

答案 0 :(得分:1)

另一种方法是使用np.take

header = a[:,0,0]
sorted = np.take(a, np.argsort(header), axis=0)

答案 1 :(得分:0)

在这里,我们可以使用一个简单的示例来演示您的代码在做什么:

首先,我们创建一个随机的3D numpy矩阵:

a = (np.random.rand(3,3,2)*10).astype(int)
array([[[3, 1],
        [3, 7],
        [0, 3]],
       [[2, 9],
        [1, 0],
        [9, 2]],
       [[9, 2],
        [8, 8],
        [8, 0]]])

然后a[:]本身将得到a,而a[:][0][0]只是a中第一个2D数组的第一行,即:

a[:][0]
# array([[3, 1],
#        [3, 7],
#        [0, 3]])

a[:][0][0]
# array([3, 1])

在此示例中,您想要的是标题3,2,9,因此我们可以使用a[:, 0, 0]来提取它们:

a[:,0,0]
# array([3, 2, 9])

现在,我们对上面的列表进行排序并获得一个索引数组:

np.argsort(a[:,0,0])
# array([1, 0, 2])

为了重新排列整个3D数组,我们需要以正确的顺序对数组进行切片。 np.arange(len(a))[:,np.newaxis]等于np.arange(len(a)).reshape(-1,1),它创建了一个连续的2D索引数组:

np.arange(len(a))[:,np.newaxis]
# array([[0],
#        [1],
#        [2]])

没有2D数组,我们会将数组切成2维

a[np.arange(3), np.argsort(a[:,0,0])]
# array([[3, 7],
#        [2, 9],
#        [8, 0]])

使用2D数组,我们可以执行3D切片并保持形状:

a[np.arange(3).reshape(-1,1), np.argsort(a[:,0,0])]
array([[[3, 7],
        [3, 1],
        [0, 3]],
       [[1, 0],
        [2, 9],
        [9, 2]],
       [[8, 8],
        [9, 2],
        [8, 0]]])

以上是您想要的最终结果。

编辑:

要排列2D数组:,可以使用:

a[np.argsort(a[:,0,0])]
array([[[2, 9],
        [1, 0],
        [9, 2]],
       [[3, 1],
        [3, 7],
        [0, 3]],
       [[9, 2],
        [8, 8],
        [8, 0]]])