【问题标题】:How to modify the sorting results of a numpy array如何修改numpy数组的排序结果
【发布时间】:2021-03-09 05:34:30
【问题描述】:

我想根据两列的值和第三列的条件对数组进行排序。这是我的数组:

my_array = np.array([[1., 2., 5.1],
                     [1., 1., 5.],
                     [2., 2., 2.],
                     [2., 1., 2.],
                     [2., 2., 5.],
                     [3., 2., 2.5],
                     [3., 1., 2.5],
                     [2., 1., 5.]])

我必须根据第一列和第二列以及基于第三列的条件对其进行排序。我试过这个方法:

my_sorted_array = my_array[np.lexsort((my_array[:, 1], my_array[:, 0]))]

但它不考虑我的第三列。它给了我:

result = np.array([[1. , 1. , 5. ],
                   [1. , 2. , 5.1 ],
                   [2., 1. , 2. ],
                   [2., 1. , 5. ],
                   [2. , 2. , 2. ],
                   [2. , 2. , 5. ],
                   [3. , 1. , 2.5 ],
                   [3. , 2. , 2.5 ]])

我想要以下输出:

my_sorted_array = np.array([[1., 1., 5.],
                            [1., 2., 5.1],
                            [2., 1., 5.],
                            [2., 2., 5.],
                            [2., 1., 2.],
                            [2., 2., 2.],
                            [3., 1., 2.5],
                            [3., 2., 2.5]])

我也尝试使用这种方法将系数设置为第三列:

sort_func = my_array[:, 0] * c1 + my_array[:, 1] * c2 + my_array[:, 2] * c3 # c1, c2 and c3 are coefficient
sort_index = np.argsort(sort_func)

这种方法也很耗时,因为我应该为每个新数据集调整 coefficinet。是否可以在排序中放置 if_condition ?如何将result 重新排列为my_sorted_array?前两列的数据总是温和而规则的(它们是规则网格的xy)。

为了更直观,我在这里上传了一个图。该图显示了我想用来对数据进行排序的趋势。

【问题讨论】:

  • 你能解释一下确切的排序顺序是什么吗?您将如何使用数据手动比较两行?
  • 亲爱的@Mad Physicist,我的数据是坐标(xyz)我想先根据x 对它们进行排序,然后再根据y 对它们进行排序。我有一个z 数据的常规网格(xy)。我的问题是,如果某些 z 值较低的数据也具有较低的 x 值,并且出现在具有较高 z 值的值中。我将上传一张我的真实数据的照片,以展示我喜欢如何对它们进行排序。
  • 解释逻辑。现在弄清楚要准确地表达您的标准,而不是在黑暗中刺伤。你显然不只是按 x 和 y 排序
  • 亲爱的@Mad Physicist,逻辑是先按x排序,再按y排序,但也有例外,当z值变化很大时。如果我可以将我的数据分成上下两部分,那么单独对每个集合进行排序然后合并它们可能会更容易。例如,在我的图中,编号为 1、2、3 和 4 的点是一组,而 5、6、7 和 8 是另一组。然后,分别对每个集合进行排序,最后再次合并它们。主要问题是我使用的是真实的自然数据,而且它们真的很混乱。
  • 这就是我认为您正在做的事情:您正在对z 设置阈值,并按顺序排序(z > threshxy)。第一项是布尔掩码,您现在可以使用z.mean 作为阈值。够近了吗?

标签: python arrays numpy sorting


【解决方案1】:

根据我们的讨论,您希望首先对z 的某个分类函数进行排序,然后是x,然后是y。因此,总的来说,与您的原始代码非常相似,为了清晰起见,稍微重新排列:

x, y, z = my_array.T
index = np.lexsort((y, x, f(z)))
my_sorted_array = my_array[index, :]

对于最简单的情况,您可以让f(x) 返回一个布尔掩码。这非常适合您的玩具示例,因为它将数据分为两类。请记住,标记为False 的点将位于标记为True 的点之前,并相应地应用您的阈值:

def f(z):
    return z < z.mean()

但是为什么要停留在两个类别上呢?您可以使用np.digitize 将数据拆分为任意数量的标签:

breaks = [2.25, 4.9]

def f(z):
    return np.digitize(z, np.sort(breaks)[::-1])

更具体地说,如果您的数据有一对大致相等的团块,您可以通过以下方式隔离它们之间的垃圾:

def f(z):
    mask0 = z > z.mean()
    z1 = z[mask0]
    z2 = z[~mask0]
    breaks = [z1.mean() - 3 * z1.std(), z2.mean() + 3 * z2.std()]
    return np.digitize(z, breaks)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    • 2022-10-12
    相关资源
    最近更新 更多