代码之家  ›  专栏  ›  技术社区  ›  mon

有没有一种方法可以将sum()应用于数组的迭代追加

  •  0
  • mon  · 技术社区  · 4 年前

    对于那些不受欢迎的人来说, sum() 适用于从左到右追加多个切片。

    import numpy as np
    _list = list(range(15))
    print("iterables is {}".format(_list))
    
    print(sum(
        [ _list[_slice] for _slice in np.s_[1:3, 5:7, 9:11] ], 
        start=[]
    ))
    ---
    List is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
    [1, 2, 5, 6, 9, 10]
    

    它不能简单地应用于numpy数组。

    import numpy as np
    _list = np.arange(15)
    print("List is {}\n".format(_list))
    
    print(sum(
        [ _list[_slice] for _slice in np.s_[1:3, 5:7, 9:11] ], 
        start=[]
    ))
    ---
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-66-a9d278e659c8> in <module>
          3 print("List is {}\n".format(_list))
          4 
    ----> 5 print(sum(
          6     [ _list[_slice] for _slice in np.s_[1:3, 5:7, 9:11] ],
          7     start=[]
    
    ValueError: operands could not be broadcast together with shapes (0,) (2,) 
    

    我想numpy way是下面这样的。

    import numpy as np
    a = np.arange(15).astype(np.int32)
    print("array is {}\n".format(a))
    
    print([a[_slice] for _slice in slices])
    np.concatenate([a[_slice] for _slice in slices])
    ---
    array is [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]
    
    [array([1, 2], dtype=int32), array([5, 6], dtype=int32), array([ 9, 10], dtype=int32)]
    array([ 1,  2,  5,  6,  9, 10], dtype=int32)
    

    问题

    有没有一种方法可以应用sum()。除此之外还有更好的方法吗 np.concatenate ?

    1 回复  |  直到 4 年前
        1
  •  1
  •   hpaulj    4 年前
    In [38]: np.s_[1:3, 5:7, 9:11]
    Out[38]: (slice(1, 3, None), slice(5, 7, None), slice(9, 11, None))
    

    np.r_ 可以制作一个复合索引——基本上是 aranges :

    In [39]: np.r_[1:3, 5:7, 9:11]
    Out[39]: array([ 1,  2,  5,  6,  9, 10])
    

    或者,创建切片对象,索引并连接:

    In [40]: x = np.s_[1:3, 5:7, 9:11]
    In [41]: y = np.arange(20)
    In [42]: np.concatenate([y[s] for s in x])
    Out[42]: array([ 1,  2,  5,  6,  9, 10])
    

    当我在过去看到这一点时,表现是相似的。

    使用列表联接创建索引的方法:

    In [46]: list(range(1,3))+list(range(5,7))+list(range(9,11))
    Out[46]: [1, 2, 5, 6, 9, 10]
    
    In [50]: sum([list(range(i,j)) for i,j in [(1,3),(5,7),(9,11)]],start=[])
    Out[50]: [1, 2, 5, 6, 9, 10]
    

    sum(..., start=[]) 只是一种串联的列表方式,使用 + 列表的定义。

    In [55]: alist = []
    In [56]: for i,j in [(1,3),(5,7),(9,11)]: alist.extend(range(i,j))
    In [57]: alist
    Out[57]: [1, 2, 5, 6, 9, 10]