2015-02-08 196 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)