顺时针对ndarray进行排序的Numpyic方法?

我正在尝试顺时针(按升序)对 numpy ndarray 进行排序。您可以将其理解为获取数组中的所有值,对它们进行排序,然后将它们按顺时针螺旋排列成具有相同形状的新数组。顺时针螺旋的方向如下图所示:

例如,假设我有一个数组

import numpy as np
a1 = np.array(([2, 4, 6],
               [1, 5, 3],
               [7, 9, 8]))

预期的输出是

np.array([[1, 2, 3],
          [8, 9, 4],
          [7, 6, 5]])

如果我有一个数组

a2 = np.array(([2, 4, 6],
               [1, 5, 3],
               [7, 9, 8],
               [12, 11, 10]))

预期的输出是

np.array([[1, 2, 3],
          [10, 11, 4],
          [9, 12, 5],
          [8, 7, 6]])

到目前为止我尝试过的

我的想法是跟踪移动迭代器的行索引x和列索引y以及cur排序后的扁平列表的当前索引sa。移动迭代器水平通过行和垂直lenr通过列时,将通过 ( lenc)的行数和通过 ( ) 的列数减去。这是我设法编写的函数:1lenrlenc

def clockwise_sorted(a, key=None, reverse=False):
    nr, nc = a.shape
    res = a.tolist()
    sa = a.ravel().tolist()
    if key is None:
        sa.sort(reverse=reverse)
    else:
        sa.sort(key=key, reverse=reverse)
    res[0] = sa[:nc]
    cur, lenr, lenc = nc, nr - 1, nc - 1
    x, y = 0, nc - 1
    while (lenc > 0 and lenr > 0):
        # go down, then go left
        for _ in range(lenr):
            x += 1
            res[x][y] = sa[cur]
            cur += 1
        for _ in range(lenc):
            y -= 1
            res[x][y] = sa[cur]
            cur += 1      
        lenr -= 1
        lenc -= 1
        
        # go up, then go right
        for _ in range(lenr):
            x -= 1
            res[x][y] = sa[cur]
            cur += 1
        for _ in range(lenc):
            y += 1 
            res[x][y] = sa[cur]
            cur += 1
        lenr -= 1
        lenc -= 1
    return np.array(res)

对于方阵,我的代码工作正常:

print(clockwise_sorted(a1))
#[[1 2 3]
# [8 9 4]
# [7 6 5]]
#%timeit 5.98 µs ± 413 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

但它不适用于非方阵:

print(clockwise_sorted(a2))
#[[ 1  2  3]
# [10 11  4]
# [ 9  9  5]
# [ 8  7  6]]

显然,它错过了12at [2,1]

请注意,我不希望您理解并修复我的代码。我不太喜欢我的代码,因为我觉得应该有更多的 numpyic 方法来做到这一点。因此,我想看到一些 numpyic 解决方案。但是,如果有人可以评论我的代码有什么问题,那就太好了。

回答

您可以使用numpy.rot90递归在数组上顺时针旋转。修改成1d后对数组的值进行排序,通过它编辑数组中的值

def rotate(matrix, arr):
    if not len(matrix):
        return
    matrix[0] = arr[:len(matrix[0])]
    rotate(np.rot90(matrix[1:]), arr[len(matrix[0]):])

a1 = np.array(([2, 4, 6],
                [1, 5, 3],
                [7, 9, 8]))

sorted_arr = sorted(a1.ravel())
rotate(a1, sorted_arr)
print(a1)

输出

[[1 2 3]
 [8 9 4]
 [7 6 5]]


以上是顺时针对ndarray进行排序的Numpyic方法?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>