2015-05-18 144 views
-2

可以使用numpy生成重复的索引模式,例如。有没有办法使用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中为三角形生成索引。

因此对于一个圆形的泛光灯我有这样的代码。

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) 
+0

第二个例子没什么意义,你能解释一下吗? –

+0

您是否遇到过比(x)范围更快的需求?有一些东西,比如linspace和mgrid,你可能会屈从于你的目的,但我认为它们不会比使用xrange快得多。 –

+0

另外,如果你能告诉我们你现在有什么(你说你当前正在使用python列表),我们可能会给你一些加速的提示。 –

回答

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]]) 

我可以生产与2号的变化第一个模式中(0初始柱破坏模式)

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]) 

或不拉威尔:

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

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

+0

多数民众赞成我认为可能有一些简单的numpy,但这是我在一个numpy解决方案后。这也给了我一个研究各种方法的方向。 – Oly

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 

你可以找到自己stltools包GitHub上this code

它的工作原理是这样的;

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

+0

这就是我以后的事情,但不是按顺序排列,而是按重复顺序排列,但不是一个接一个地排列,因为它会重复索引和分数。你也可以使用np.arrange,如果你按照这种方式排列它们,可以跳过生成列表。 – Oly

+0

@Oly很抱歉,我无法理解您的评论。此代码将唯一点的列表和唯一点的索引数组返回到唯一点的数组中。 –

+0

史密斯我的坏我没有完全理解它,我觉得它有点混乱,因为它使用的字符串元组和数组,不错的例子,但不是我想要的。 – Oly

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只要你想多少组生成,您可以将其更改为适合您的三角形上下的requiremen TS。

+0

感谢这个例子,它是一种有趣的方式,我会对它进行一些研究,然后仔细研究一下,因为我对这种方法不太了解。 – Oly

+0

@Oly,是的,有一个游戏,我希望这会有所帮助,'numpy.concatenate'基本上是连接一个数组序列。 – Anzel

相关问题