Python 有没有一种方法可以使用numpy生成索引列表

Python 有没有一种方法可以使用numpy生成索引列表,python,numpy,dynamically-generated,indices,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,我有一

例如,我可以使用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)

我不确定我是否完全理解你的意思,但以下是我用来为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上的我的软件包中找到

它是这样工作的

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
的长度是值。实际上,这个值是第一次看到这个精确的点。

我不是100%确定这是你想要的,我想你可以使用一对
范围
值和增量
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
作为要生成的组数,您可以更改此值以满足您的要求。

您的第一个示例可以通过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个阵列产生):

我可以生成第一个图案,第二个图案有变化(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])
或者没有拉威尔:

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

虽然我不知道是什么参数产生了你的例子。

第二个例子没有多大意义,你能解释一下吗?你有没有遇到过需要比(x)范围更快的东西?有些东西,比如linspace和mgrid,您可能会满足您的需求,但我认为它们不会比使用xrange快很多。另外,如果您能向我们展示您现在拥有的东西(您说您目前正在使用python列表),我们也许可以给你一些加速的建议。
0,1,2,1,2,3,4,5,6,5,6,7
是如何产生的?我已经修改了上面的问题,让你知道我在做什么。这是我要做的,但不是按顺序,按重复的顺序,但不是一个接一个,因为重复的是索引和点。此外,如果您以这种方式将列表按顺序排列,您可能还可以使用np.arrange并跳过生成列表。@Oly很抱歉,但我无法理解您的评论。这段代码将唯一点列表和所有点的索引数组返回到唯一点数组中。Smith我的错我没有完全理解它,我发现它有点混乱,因为它使用dicts元组和数组,很好的例子,但不完全是我想要的。那太好了,我以为numpy中可能有更简单的东西,但这就是我想要的numpy解决方案。这也给了我一个研究各种方法的方向。感谢这个例子,这是一种有趣的方法,我将对它进行一次尝试,并进一步研究串联,因为我对该方法知之甚少。@Oly,是的,进行一次尝试,我希望这会有所帮助,
numpy。基本上通过将数组序列连接在一起来连接。
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])
array([[0, 1, 2],
       [0, 2, 3],
       [0, 3, 4],
       [0, 4, 5],
       [0, 5, 6],
       [0, 6, 7],
       [0, 7, 8]])