np.lexsort可以在升序和降序之间切换。

3

我有一个包含 x 列的 numpy 数组,想要按照多列排序(其中一些可能是类型为 np.str_ 的列)。我知道可以使用np.lexsort实现此目的。

是否有办法指定每个排序列的升序/降序顺序?

例如:我知道可以通过以下方式按多列排序:

(已编辑以表示字符串列!)
import numpy as np
arr = np.array([list("aaabbb"),[1,2,3,1,4,3],[1,2,3,4,6,6]]).T # Define arr
idx = np.lexsort([arr[:,1], arr[:,2]]) # sort by column 2 and then by column 1 (i.e. reversed order)
arr = arr[idx]

我也理解可以按照以下方式降序排序:

arr = arr[idx[::-1]]

这将导致第一个排序列(第二列)为降序,随后的列为升序。

但是,我如何指定要使第一个排序(第二列)按降序排列,而随后的排序(第一列)按降序排列,以便获得以下结果。

期望输出

array([['b', 4, 6],
       ['b', 3, 6],
       ['b', 1, 4],
       ['a', 3, 3],
       ['a', 2, 2],
       ['a', 1, 1]]

基本上,对于我的例子,我正在寻找与以下内容等效的东西:

df = pd.DataFrame(arr, columns=list("abc"))
df.sort_values(by=["c","b"], ascending=[False, False])

通常情况下,我希望能够指定(i)要排序的列和(ii)每列的排序顺序(升序/降序)。


你想要的输出是什么? - U13-Forward
编辑以使期望的输出更明显 - FredMaster
已回答!很棒的问题。 - U13-Forward
1个回答

5

尝试使用减号进行反转,它基本上通过每个值的负数进行排序,这实际上是有效的:

idx = np.lexsort([arr[:,1], -arr[:,2]])

输出:

array([[2, 3, 6],
       [2, 4, 6],
       [2, 1, 4],
       [1, 3, 3],
       [1, 2, 2],
       [1, 1, 1]])

如果出现字符串问题,请尝试以下方法:
idx = np.lexsort([arr[:,1], arr[:,2]])
arr = arr[idx]
arr[:, 0] = arr[:, 0][::-1]

输出:

array([['2', '1', '1'],
       ['2', '2', '2'],
       ['2', '3', '3'],
       ['1', '1', '4'],
       ['1', '3', '6'],
       ['1', '4', '6']], 
      dtype='<U11')

编辑:

根据最新的修改:

arr = arr[::-1]

可以工作:

array([['b', '4', '6'],
       ['b', '3', '6'],
       ['b', '1', '4'],
       ['a', '3', '3'],
       ['a', '2', '2'],
       ['a', '1', '1']], 
      dtype='<U1')

谢谢。但是这对于np.str_情况不起作用,因为我不能乘以-1。或者我错了吗? - FredMaster
@FredMaster 我不太明白你的意思,你应该先尝试一下,可能会起作用。 - U13-Forward
如果其中一列的类型为字符串,则它将无法工作。例如,如果您切换到 arr = np.array([list("aaabbb"),[1,2,3,1,4,3],[1,2,3,4,6,6]]).T,您的解决方案将无法工作。 - FredMaster
@FredMaster 请看一下我的第二个代码,使用了切片,那个可以运行。 - U13-Forward
感谢您的回复。不幸的是,这仍然没有解决我的问题。请注意,我的 arr 只是一个玩具示例。这也适用于我示例的第一行中指定的其他数组。 - FredMaster
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接