圆形numpy数组索引

时间:2015-02-08 19:16:57

标签: python numpy indexing

我有一个n-n 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到{{1}的所有元素}。

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

4 个答案:

答案 0 :(得分:8)

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],或者您更喜欢[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))

答案 1 :(得分:3)

不幸的是,你不能通过切片来做到这一点,你需要连接到两个部分:

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]

答案 2 :(得分:2)

您可以使用的另一种方法是将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

答案 3 :(得分: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)