【问题标题】:circular numpy array indices圆形numpy数组索引
【发布时间】:2015-04-08 12:15:30
【问题描述】:

我有一个一维 numpy 数组 a = [1,2,3,4,5,6] 和一个函数,它获取两个输入 starting_indexending_index,并返回 a[staring_index:ending_index]

很明显,当ending_index 小于starting_index 时,我遇到了麻烦。在这种情况下,函数应该从starting_index开始并以循环方式遍历向量a,即返回starting_index之后的所有元素加上索引0到ending_index的所有元素。

例如,如果starting_index=4ending_index=1 则输出应为output = [5,6,1]。我可以使用if 条件来实现它,但我想知道是否有任何 Pythonic 和简洁的方法来实现它?

【问题讨论】:

标签: python numpy indexing


【解决方案1】:

np.take 有一个wrap 模式:

In [171]: np.take(np.arange(1,7),range(4,7),mode='wrap')
Out[171]: array([5, 6, 1])

这不是你想要的。

实际上,模数也是如此

In [177]: a[np.array([4,5,6])%6]
Out[177]: array([5, 6, 1])

但是,如果你更喜欢 [4, 5, 0] 或者你更喜欢 [4, 5, 0] 的小函数呢?

def foo(a, start, stop): 
    # fn to convert your start stop to a wrapped range
    if stop<=start:
        stop += len(a)
    return np.arange(start, stop)%len(a)

a[foo(a,4,1)]  # or
np.take(a,foo(a,4,1))

【讨论】:

  • 不应该在方法 foo 的返回语句中取模以使其工作吗?
【解决方案2】:

这个循环永远。

def circular_indices(lb, ub, thresh):
    indices = []
    while True:
        stop = min(ub, thresh)
        ix = np.arange(lb, stop)
        indices.append(ix)
        if stop != ub:
            diff = ub - stop
            lb = 0
            ub = diff
        else:
            break

    return np.concatenate(indices)

【讨论】:

    【解决方案3】:

    您可以使用的替代方法是结合索引的 numpy roll 函数:

    # -*- coding: utf-8 -*-
    import numpy as np
    
    def circular_array(starting_index, ending_index):
    
        idx = np.arange(1,7)
        idx = np.roll(idx, -starting_index)[:(len(idx)-starting_index+ending_index)%len(idx)]
    
        return idx
    
    
    a = circular_array(4, 1)
    print a
    

    【讨论】:

      【解决方案4】:

      很遗憾,您无法通过切片来执行此操作,您需要连接到两个片段:

      import numpy as np
      
      a = [1, 2, 3, 4, 5, 6]
      if starting_index > ending_index:
          part1 = a[start_index:]
          part2 = a[:end_index]
          result = np.concatenate([part1, part2])
      else:
          result = a[start_index:end_index]
      

      【讨论】:

      • 目前我正在做这样的事情。谢谢。但是,不能与 numpy 一起使用,你能解释更多关于切片的信息吗?我认为它可以与列表一起使用?
      • Numpy 索引和切片被描述为here 还有一个更一般的切片讨论here
      • 我可以确认这比使用 np.roll 更快,尤其是对于较小 (
      猜你喜欢
      • 1970-01-01
      • 2018-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-23
      • 2011-11-18
      • 1970-01-01
      • 2021-04-17
      相关资源
      最近更新 更多