2015-02-08 15 views
6

Tôi có một mảng numpy 1-D a = [1,2,3,4,5,6] và một hàm nhận hai đầu vào, starting_indexending_index và trả về a[staring_index:ending_index].Chỉ số mảng dạng vòng tròn

Rõ ràng là tôi gặp rắc rối khi ending_index nhỏ hơn starting_index. Trong trường hợp này, hàm sẽ bắt đầu từ start_index và đi qua vector a theo cách tròn, tức là trả về tất cả các phần tử đến sau starting_index cộng với tất cả các phần tử từ chỉ mục 0 đến số ending_index.

Ví dụ: nếu starting_index=4ending_index=1 thì đầu ra phải là output = [5,6,1]. Tôi có thể thực hiện nó với một điều kiện if nhưng tôi đã tự hỏi nếu có bất kỳ cách Pythonic và súc tích để làm điều đó?

+1

này dường như liên quan: https://scimusing.wordpress.com/2013/10/25/ring-buffers-in-pythonnumpy/ – endolith

Trả lời

4

np.take có chế độ wrap:

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

Đó không phải là điều bạn muốn.

Trên thực tế, mô đun làm điều tương tự

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

Nhưng làm thế nào về một chức năng nhỏ có thể biến thành (4,1)[4, 5, 6], hoặc nếu bạn thích ?

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

Không nên là modulo trong câu lệnh trả về của phương thức foo để làm việc này? – Ozgar

+0

@Ozgar, cảm ơn; sửa chữa. – hpaulj

3

Đáng tiếc là bạn không thể làm điều này với cắt, bạn sẽ cần phải concatonate đến hai phân đoạn:

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

hiện tôi đang làm một cái gì đó như thế này. Cảm ơn. mặc dù, không thể được sử dụng với numpy, bạn sẽ giải thích thêm về slicing? Tôi cho rằng nó có thể được sử dụng với danh sách? – TNM

+0

Lập chỉ mục và chia cắt theo khối được mô tả [ở đây] (http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#basic-slicing-and-indexing) cũng có một cuộc thảo luận chung hơn về việc cắt [tại đây] (https://docs.python.org/2.3/whatsnew/section-slices.html). –

1

Một thay thế mà bạn có thể sử dụng được chức năng NumPy roll kết hợp với lập chỉ mục:

# -*- 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

Vòng kết nối này mãi mãi.

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) 
Các vấn đề liên quan