【问题标题】:process some iterations on python ndarray在 python ndarray 上处理一些迭代
【发布时间】:2016-07-02 16:35:43
【问题描述】:

我创建了两个相同长度的排序 ndarray,并通过 vstack() 将它们连接起来。 我在下面将我的数组称为:

[[x1 y1][x2 y2][x3 y3][x4 y4]].

然而,实际上我在每个条目中都有不同的 x 值,但 y 只有几个不同的值,从 0 上升到 n

所以我得到了这样的东西:

[[x1 0],[x2 0],[x3 0],[x4 1],[x5 1],[x6 2],[x7 2],[x8 2][x9 3][x10 3]...]

我的目标是创建一个循环来获取所有不同 y 值的第一个和最后一个 x 值。这样循环就会返回x1x3 (y == 0)、x4x5 (y == 1)、x6x8 (y == 2) 等等。

我目前正在为此尝试一个丑陋的解决方案,为所有不同的 y 值创建子数组,这样我就可以获取每个数组的第一个和最后一个元素来获得我需要的 y 值,但我是想知道实现这一目标的最有效或 Pythonic 方式是什么样的。

【问题讨论】:

  • 向我们展示丑陋的方式;这样可以更轻松地提出改进建议。

标签: python arrays loops numpy multidimensional-array


【解决方案1】:

您可以使用 2 列表理解。在第一个中,您可以使用itertools.groupby() 来根据子列表的第二个元素对子列表进行分组,然后选择第一个和最后一个。

>>> from itertools import groupby
>>> from operator import itemgetter
>>> 
>>> groups = [list(g) for _, g in groupby(lst, key=itemgetter(1))]
>>> 
>>> [sub if len(sub)<2 else [sub[0], sub[-1]] for sub in groups]
[[['x1', 0], ['x3', 0]], [['x4', 1], ['x5', 1]], [['x6', 2], ['x8', 2]], [['x9', 3], ['x10', 3]]]

【讨论】:

    【解决方案2】:

    default_dict 是收集此类值的好方法

    定义数组(希望我可以简单地复制粘贴):

    In [186]: A=np.array([[1, 0],[2, 0],[3, 0],[4 ,1],[5 ,1],[6, 2],[7, 2],[8 ,2],[9 ,3],[10 ,3]])
    In [187]: A
    Out[187]: 
    array([[ 1,  0],
           [ 2,  0],
           [ 3,  0],
           [ 4,  1],
           [ 5,  1],
           [ 6,  2],
           [ 7,  2],
           [ 8,  2],
           [ 9,  3],
           [10,  3]])
    

    制作字典,默认值为list(),并追加数组行:

    In [188]: from collections import defaultdict
    In [189]: dd = defaultdict(list)
    In [190]: for row in A:
       .....:     dd[row[1]].append(row)
       .....:     
    In [191]: dd
    Out[191]: defaultdict(<class 'list'>, {0: [array([1, 0]), array([2, 0]), array([3, 0])], 1: [array([4, 1]), array([5, 1])], 2: [array([6, 2]), array([7, 2]), array([8, 2])], 3: [array([9, 3]), array([10,  3])]})
    

    我可以将第一个和最后一个值提取到另一个字典中:

    In [192]: {key:[value[0],value[-1]] for key,value in dd.items()}
    Out[192]: 
    {0: [array([1, 0]), array([3, 0])],
     1: [array([4, 1]), array([5, 1])],
     2: [array([6, 2]), array([8, 2])],
     3: [array([9, 3]), array([10,  3])]}
    

    或者我可以在列表等或 3d 数组中收集值

    In [195]: np.array([np.array([value[0],value[-1]]) for key,value in dd.items()]) 
    Out[195]: 
    array([[[ 1,  0],
            [ 3,  0]],
    
           [[ 4,  1],
            [ 5,  1]],
    
           [[ 6,  2],
            [ 8,  2]],
    
           [[ 9,  3],
            [10,  3]]])
    

    itertools.groupby 很好,而且可能更快。但是您需要熟悉生成器。

    如果对y 值进行了排序,您可以找到值发生变化的值,并使用这些索引来拆分数组。

    【讨论】:

      猜你喜欢
      • 2017-07-25
      • 1970-01-01
      • 2017-11-17
      • 2022-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      相关资源
      最近更新 更多