首页 > 解决方案 > 对 3d 数组的配对数组进行排序(替换循环)

问题描述

我有以下 3d 数组:

import numpy as np

z = np.array([[[10,  2],
               [ 5,  3],
               [ 4,  4]],
              [[ 7,  6],
               [ 4,  2],
               [ 5,  8]]])

我想根据 3rd dim & 1st 值对它们进行排序。

目前我正在使用以下代码:

from operator import itemgetter

np.array([sorted(x,key=itemgetter(0)) for x in z])
array([[[ 4,  4],
        [ 5,  3],
        [10,  2]],

       [[ 4,  2],
        [ 5,  8],
        [ 7,  6]]])

我想通过删除 for 循环使代码更高效/更快?

标签: pythonarraysnumpysortingvectorization

解决方案


您可以在没有-loop的情况下使用map()来实现相同的结果。for并且 sort 函数可以是用户定义的,也可以是 lambda,或者是 的一部分sorted

  1. 首先创建一个排序函数:

    >>> def mysort(it):
    ...   return sorted(it, key=itemgetter(0))
    ...
    >>> list(map(mysort, z))
    [[[4, 4], [5, 3], [10, 2]], [[4, 2], [5, 8], [7, 6]]]
    
  2. 与上面相同,但使用 lambda 代替:

    >>> list(map(lambda it: sorted(it, key=itemgetter(0)), z))
    [[[4, 4], [5, 3], [10, 2]], [[4, 2], [5, 8], [7, 6]]]
    
  3. 有一个partial

    >>> from functools import partial
    >>> psort = partial(sorted, key=itemgetter(0))
    >>> list(map(psort, z))
    [[[4, 4], [5, 3], [10, 2]], [[4, 2], [5, 8], [7, 6]]]
    

    或部分就地定义:

    >>> list(map(partial(sorted, key=itemgetter(0)), z))
    [[[4, 4], [5, 3], [10, 2]], [[4, 2], [5, 8], [7, 6]]]
    
  4. 您的问题有一个列表列表,而不是 3d numpy 数组。对于面向 numpy 的解决方案,请参阅此答案

仅供参考,(2)和(3b)大致等价,但有它们的区别
在选项 1-3 中,我更喜欢 (2) 中的 lambda。


推荐阅读