首页 > 解决方案 > 基于多列的有序序列对 2D numpy 数组进行排序/聚类

问题描述

我有一个像这样的二维 numpy 数组:

 [[4 5 2] 
  [5 5 1]
  [5 4 5]
  [5 3 4]
  [5 4 4]
  [4 3 2]]

我想通过在数组中找到这样的序列来排序/聚类这个数组row[0]>=row[1]>=row[2]row[0]>=row[2]>row[1]......所以数组的行是有序的。

我尝试使用 code: lexdf = df[np.lexsort((df[:,2], df[:,1],df[:,0]))][::-1],但这不是我想要的。lexsort 的输出:

 [[5 5 1]
  [5 4 5]
  [5 4 4]
  [5 3 4]
  [4 5 2] 
  [4 3 2]]

我想要的输出:

 [[5 5 1]
  [5 4 4]
  [4 3 2]
  [5 4 5]
  [5 3 4]
  [4 5 2]] 

或将其分为三个部分:

 [[5 5 1]
 [5 4 4]
 [4 3 2]]

 [[5 4 5]
 [5 3 4]]

 [[4 5 2]]

而且我想将此应用于具有更多列的数组,因此最好不进行迭代。产生这种输出的任何想法?

标签: pythonarraysnumpysortingsequence

解决方案


我不知道如何在 numpy 中做到这一点,除非可能有一些奇怪的 function hacks numpy.split

这是一种使用 python 列表获取组的方法:

from itertools import groupby, pairwise

def f(sublist):
    return [x <= y for x,y in pairwise(sublist)]

# NOTE: itertools.pairwise requires python>=3.10
# For python<=3.9, use one of those alternatives:
# * more_itertools.pairwise(sublist)
# * zip(sublist, sublist[1:])

a = [[4, 5, 2], 
  [5, 5, 1],
  [5, 4, 5],
  [5, 3, 4],
  [5, 4, 4],
  [4, 3, 2]]

b = [list(g) for _,g in groupby(sorted(a, key=f), key=f)]

print(b)
# [[[4, 3, 2]],
#  [[5, 4, 5], [5, 3, 4], [5, 4, 4]],
#  [[4, 5, 2], [5, 5, 1]]]

注意: groupby+sorted 的组合实际上效率稍低,因为sorted需要 n log(n) 时间。线性替代方法是使用列表字典进行分组。参见模块中的实例函数itertoolz.groupbytoolz


推荐阅读