我想以特定顺序对一个np.array进行排序,例如,我有一个输入数组a:
a = np.array([[ 2, 2, 1,], [ 3, 3, 3,], [ 2, 3, 2,]])
我希望得到的输出是:
b = np.array([[ 2, 3, 2,], [ 3, 1, 3,], [ 2, 3, 2,]])
您可能会猜到,这种排序的目的是在数组中创造一种对称性(此外还有其他不相关的因素)。
我的问题是,我只是通过随机打乱来尝试排序数组:
iNumbers = 0while !symmetry(a) and iNumbers != 3000: np.random.shuffle(a.flat) iNumbers += 1
其中symmetry
函数在元素排列符合标准时返回True。
因此,我正在寻找更有效的方法来排序数组以通过我的评估函数。
我是否应该对这个问题应用机器学习技术?
此外,我也在寻找任何建议、评论、想法或意见…
回答:
请注意,您有对称性是因为您的元素允许这样(有足够的3、2和1来实现对称性)。假设您考虑了这一点,您寻找的是一种径向排序。以下算法可以实现这一点:
import numpy as npdef sortRadially(a): X, Y = np.indices(a.shape, dtype="float") c = int(a.shape[0]/2) d = np.sqrt((c-X)**2 + (c-Y)**2) fd = d.flatten() fX = X.flatten() fY = Y.flatten() argD = fd.argsort() nX = fX[argD].astype(int) nY = fY[argD].astype(int) fa = a.flatten() sa = a.copy() fa.sort() for i in range(nX.shape[0]): a[nX[i], nY[i]] = fa[i] return aa = np.array([[ 2, 2, 1,], [ 3, 3, 3,], [ 2, 3, 2,]])myown = np.random.randint(0, 100, (9, 9))print("Your test:")print(sortRadially(a))print("")print("My test:")print(sortRadially(myown))
结果如下:
Your test:[[3 2 3] [2 1 2] [3 2 3]]My test:[[97 95 91 78 60 73 84 92 98] [93 78 55 44 30 34 55 80 92] [84 45 22 15 10 17 23 44 88] [71 42 12 7 2 7 16 42 73] [69 28 10 2 0 1 10 28 66] [72 44 13 5 1 3 14 38 77] [87 49 19 14 8 19 24 52 91] [95 83 48 43 33 39 52 79 94] [98 94 83 73 67 71 91 96 99]]
我不是排序算法的专家,可能有更快的方法来实现这一点,但这肯定比随机打乱并等待最佳结果要快得多。
对该算法的解释如下:
-
获取所有单元格的坐标(X, Y)。
-
计算所有坐标到中心单元格的距离(在我的算法中,我假设矩阵是方形且行/列大小为奇数)。
-
对距离进行排序并获取索引(而不是距离值)。
-
对X和Y坐标应用相同的排序。
-
对原始数组进行排序。
- 按照排序后的单元格和坐标填充数组。
- 实际上没有第7步,我只是不喜欢把事情停留在6步…