【问题标题】:NumPy first and last element from arrayNumPy 数组中的第一个和最后一个元素
【发布时间】:2013-01-14 14:33:00
【问题描述】:

我正在尝试从数组中动态获取第一个和最后一个元素。

所以,让我们假设数组有 6 个元素。

test = [1,23,4,6,7,8]

如果我想获取first and last = 1,823,74,6。有没有办法按这个顺序获取元素? 我看了几个问题LinkLink2。我在这些链接的帮助下想出了这个原型..

#!/usr/bin/env python

import numpy

test = [1,23,4,6,7,8]
test1 = numpy.array([1,23,4,6,7,8])
len_test = len(test)
first_list = [0,1,2]
len_first = len(first_list)
second_list = [-1,-2,-3]
len_second = len(second_list)

for a in range(len_first):
        print numpy.array(test)[[first_list[a] , second_list[a]]]
        print test1[[first_list[a], second_list[a]]]

但是,如果您有超过 6 个元素,则此原型将无法扩展。所以,我想知道是否有办法动态获取这对元素。

谢谢!

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    我到此结束,因为我搜索了“python 数组的第一个和最后一个元素”,并找到了除此之外的所有其他内容。所以这里是标题问题的答案:

    a = [1,2,3]
    a[0] # first element (returns 1)
    a[-1] # last element (returns 3)
    

    【讨论】:

    【解决方案2】:

    怎么样:

    In [10]: arr = numpy.array([1,23,4,6,7,8])
    
    In [11]: [(arr[i], arr[-i-1]) for i in range(len(arr) // 2)]
    Out[11]: [(1, 8), (23, 7), (4, 6)]
    

    根据arr 的大小,用NumPy 编写整个东西可能会更高效:

    In [41]: arr = numpy.array([1,23,4,6,7,8]*100)
    
    In [42]: %timeit [(arr[i], arr[-i-1]) for i in range(len(arr) // 2)]
    10000 loops, best of 3: 167 us per loop
    
    In [43]: %timeit numpy.vstack((arr, arr[::-1]))[:,:len(arr)//2]
    100000 loops, best of 3: 16.4 us per loop
    

    【讨论】:

    • 但是,对于具有奇数个元素的数组,将删除一个元素。如果您改用(len(arr)+1)//2,您将在结果末尾将中间元素捕获为(middle,middle)
    • @isedev:我们真的不知道 OP 的要求是什么。也就是说,这两种方法应该涵盖所有可能性。 :)
    • @NPE:我总是会有偶数个元素。所以,这应该不是问题
    【解决方案3】:

    使用 Numpy 的精美索引:

    >>> test
    array([ 1, 23,  4,  6,  7,  8])
    
    >>> test[::-1]  # test, reversed
    array([ 8,  7,  6,  4, 23,  1])
    
    >>> numpy.vstack([test, test[::-1]])  # stack test and its reverse
    array([[ 1, 23,  4,  6,  7,  8],
           [ 8,  7,  6,  4, 23,  1]])
    
    >>> # transpose, then take the first half;
    >>> # +1 to cater to odd-length arrays
    >>> numpy.vstack([test, test[::-1]]).T[:(len(test) + 1) // 2]
    array([[ 1,  8],
           [23,  7],
           [ 4,  6]])
    

    vstack 复制数组,但所有其他操作都是常量时间指针技巧(包括反转),因此非常快。

    【讨论】:

      【解决方案4】:
      arr = np.array([1,2,3,4])
      arr[-1] # last element
      

      【讨论】:

        【解决方案5】:
        >>> test = [1,23,4,6,7,8]
        >>> from itertools import izip_longest
        >>> for e in izip_longest(test, reversed(test)):
            print e
        
        
        (1, 8)
        (23, 7)
        (4, 6)
        (6, 4)
        (7, 23)
        (8, 1)
        

        另一种选择

        >>> test = [1,23,4,6,7,8]
        >>> start, end = iter(test), reversed(test)
        >>> try:
            while True:
                print map(next, [start, end])
        except StopIteration:
            pass
        
        [1, 8]
        [23, 7]
        [4, 6]
        [6, 4]
        [7, 23]
        [8, 1]
        

        【讨论】:

        • 您正在使用您不需要的reversed(test) 在内存中创建额外的副本。
        • @SudiptaChatterjee: reversed 返回生成器而不是副本
        【解决方案6】:

        这个怎么样?

        >>> import numpy
        >>> test1 = numpy.array([1,23,4,6,7,8])
        >>> forward = iter(test1)
        >>> backward = reversed(test1)
        >>> for a in range((len(test1)+1)//2):
        ...     print forward.next(), backward.next()
        ... 
        1 8
        23 7
        4 6
        

        (len(test1)+1)//2 确保奇数长度数组的中间元素也被返回:

        >>> test1 = numpy.array([1,23,4,9,6,7,8]) # additional element '9' in the middle
        >>> forward = iter(test1)                                                      
        >>> backward = reversed(test1)
        >>> for a in range((len(test1)+1)//2):
        ...     print forward.next(), backward.next()
        1 8
        23 7
        4 6
        9 9
        

        仅使用 len(test1)//2 将删除奇数长度数组的中间元素。

        【讨论】:

          【解决方案7】:

          这样做。请注意,奇数个元素不会包含在中间的元素。

          test = [1, 23, 4, 6, 7, 8, 5]    
          for i in range(len(test)/2):
              print (test[i], test[-1-i])
          

          输出:

          (1, 5)
          (23, 8)
          (4, 7)
          

          【讨论】:

            【解决方案8】:

            您可以简单地使用take 方法和元素索引(最后一个索引可以是-1)。

            arr = np.array([1,2,3])
            
            last = arr.take(-1)
            # 3
            

            【讨论】:

              【解决方案9】:

              假设列表有偶数个元素,你可以这样做:

              test = [1,23,4,6,7,8]
              test_rest = reversed(test[:len(test)/2])
              
              for n in len(test_rest):
                  print [test[n], test_test[n]]
              

              【讨论】:

                猜你喜欢
                • 2021-12-27
                • 2011-06-06
                • 2013-12-01
                • 1970-01-01
                • 1970-01-01
                • 2017-02-27
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多