有没有办法使用numpy生成索引列表

时间:2015-05-18 17:33:06

标签: python numpy dynamically-generated indices

我可以使用numpy来生成索引的重复模式。

  

0,1,2,3,4,5,0,6,7,8,9,10,0,11,12,13,14,15

  

0,1,2,1,2,3,4,5,6,5,6,7

我是否可以使用numpy中的方法在范围之间生成这些列表?

目前我正在使用python中的列表进行此操作,但我很好奇我是否可以使用numpy来加快速度。

我不确定除了numpy.arange之外还有什么方法可以查看。

进一步澄清我正在以各种模式为opengl中的三角形生成索引。

所以对于圆圈中的traingles,我有一些像这样的代码。

    for fan_set in range(0, len(self.vertices) / vertex_length, triangle_count):
        for i in range(fan_set + 1, fan_set + 8):
            self.indices.append(fan_set)
            self.indices.append(i)
            self.indices.append(i + 1)

3 个答案:

答案 0 :(得分:0)

我不确定我到底是什么意思,但以下是我用来为3D点生成唯一索引的内容;

def indexate(points):
    """
    Convert a numpy array of points into a list of indices and an array of
    unique points.

    Arguments:
        points: A numpy array of shape (N, 3).

    Returns:
        An array of indices and an (M, 3) array of unique points.
    """
    pd = {}
    indices = [pd.setdefault(tuple(p), len(pd)) for p in points]
    pt = sorted([(v, k) for k, v in pd.items()], key=lambda x: x[0])
    unique = np.array([i[1] for i in pt])
    return np.array(indices, np.uint16), unique

您可以在github上的this code包中找到stltools

它的工作原理如下;

In [1]: import numpy as np

In [2]: points = np.array([[1,0,0], [0,0,1], [1,0,0], [0,1,0]])

In [3]: pd = {}

In [4]: indices = [pd.setdefault(tuple(p), len(pd)) for p in points]

In [5]: indices
Out[5]: [0, 1, 0, 2]

In [6]: pt = sorted([(v, k) for k, v in pd.items()], key=lambda x: x[0])

In [7]: pt
Out[7]: [(0, (1, 0, 0)), (1, (0, 0, 1)), (2, (0, 1, 0))]

In [8]: unique = np.array([i[1] for i in pt])

In [9]: unique
Out[9]: 
array([[1, 0, 0],
       [0, 0, 1],
       [0, 1, 0]])

关键点(如果你原谅双关语)是使用点的元组(因为元组是不可变的,因此可以使用)作为具有setdefault方法的字典中的键,而dict的长度是值。实际上,该值是第一次看到完全点。

答案 1 :(得分:0)

我不是100%肯定这是你所追求的,我认为你可以使用一对range值并增加n次3(每组之间的差距)来实现这一目标,然后使用numpy.concatenate连接最终数组,如下所示:

import numpy as np

def gen_list(n):
    return np.concatenate([np.array(range(i, i+3) + range(i+1, i+4)) + i*3 
                           for i in xrange(n)])

用法:

gen_list(2)
Out[16]: array([0, 1, 2, 1, 2, 3, 4, 5, 6, 5, 6, 7])

gen_list(3)
Out[17]: 
array([ 0,  1,  2,  1,  2,  3,  4,  5,  6,  5,  6,  7,  8,  9, 10,  9, 10,
       11])

list(gen_list(2))
Out[18]: [0, 1, 2, 1, 2, 3, 4, 5, 6, 5, 6, 7]

在我的示例中,我只使用n作为您要生成的群组数量,您可以更改它以满足您的三角形要求。

答案 2 :(得分:0)

您的第一个示例可以通过numpy方法生成:

In [860]: np.concatenate((np.zeros((3,1),int),np.arange(1,16).reshape(3,5)),axis=1).ravel()
Out[860]: 
array([ 0,  1,  2,  3,  4,  5,  0,  6,  7,  8,  9, 10,  0, 11, 12, 13, 14,
       15])

那是因为我看到了这个2d重复模式

array([[ 0,  1,  2,  3,  4,  5],
       [ 0,  6,  7,  8,  9, 10],
       [ 0, 11, 12, 13, 14, 15]])

第二个模式可以由这个2d数组的ravel产生(由广播2个数组产生):

In [863]: np.array([0,1,4,5])[:,None]+np.arange(3)
Out[863]: 
array([[0, 1, 2],
       [1, 2, 3],
       [4, 5, 6],
       [5, 6, 7]])

我可以生成第一个带有第二个变量的模式(0s的初始列会破坏模式)

I=np.array([0,5,10])[:,None]+np.arange(0,6)
I[:,0]=0

我认为你的双循环可以表示为列表理解为

In [872]: np.array([ [k,i,i+1] for k in range(0,1,1) for i in range(k+1,k+8)]).ravel()
Out[872]: array([0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7, 0, 7, 8])

或没有ravel:

array([[0, 1, 2],
       [0, 2, 3],
       [0, 3, 4],
       [0, 4, 5],
       [0, 5, 6],
       [0, 6, 7],
       [0, 7, 8]])

虽然我不知道哪些参数会产生你的例子。