2015-02-08 152 views
6

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

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

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

+1

这似乎与:https://scimusing.wordpress.com/2013/10/25/ring-buffers-in-pythonnumpy/ – endolith 2015-07-04 17:45:50

回答

4

np.takewrap模式:

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,1)[4, 5, 6],或者如果你喜欢?

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)) 
+0

不应该在模拟foo方法的返回语句中使用它来工作吗? – Ozgar 2018-01-25 11:05:45

+0

@Ozgar,谢谢;纠正。 – hpaulj 2018-01-25 11:21:34

3

不幸的是你不能用切片做到这一点,你需要concatonate两个部分:

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] 
+0

我目前正在做这样的事情。谢谢。虽然,不能用于numpy,你会解释更多关于切片?我认为它可以与列表一起使用? – TNM 2015-02-08 19:33:46

+0

Numpy索引和切片描述[这里](http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#basic-slicing-and-indexing)还有一个更一般的切片讨论[这里](https://docs.python.org/2.3/whatsnew/section-slices.html)。 – 2015-02-08 19:47:47

1

,您可以使用在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 
0

这圈永远。

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)