2016-02-03 55 views
0

如何获取包含特定长度的所有可能的连续子阵列的二维数组?选择长度为n的所有可能的子阵列

例如,假设我的阵列['a', 'b', 'c', 'd', 'e'],且n为3,其结果应该是

[['a', 'b', 'c'] 
['b', 'c', 'd'] 
['c', 'd', 'e']] 

我发现了一个similar question与蟒蛇名单,但我想和numpy的做到这一点,因为我需要在许多不同的阵列上执行此操作,每个阵列都相当大。基本上,速度是一个问题。

+1

你可以使用'as_strided'(参见[这里](http://stackoverflow.com/questions/4936620/using-strides-for-an-efficient-moving-average-filter)作为示例工具ntation--'rolling_window_lastaxis(a,3)'给出你的输出。) – DSM

回答

2

第三和最后的无环路的答案:

def substrings(n, x) 
    return numpy.fromfunction(lambda i, j: x[i + j], (len(x) - n + 1, n), 
          dtype=int) 

你必须来分析所有这些解决方案自己找到一个最最高效的。如果您最喜欢这些解决方案之一,请将其选为正确答案。

+0

这是迄今为止最快的方法,但似乎仍与列表理解方法的速度相同。如果有什么更好的情况出现,我会把问题留出一段时间,否则这就是赢家:) – Jezzamon

1

没有循环?好吧,我们将使用递归:

def substrings(n, x): 
    if len(x) < n: 
    return [] 

    return [x[:n]] + substrings(n, x[1:]) 

您可以轻松地修改上面的返回数组:

return array([x[:n]] + substrings(n, x[1:])) 

被警告,如果阵列是非常大的,你会超过你的最大递归深度堆栈将溢出。

+0

哈哈,我不想使用循环的原因是出于性能方面的原因。我想以某种方式用矢量操作来完成它)。我想这会比循环慢很多。我已经稍微编辑了这个问题。 – Jezzamon

+0

查看我的其他答案为矢量/矩阵方法。在非常大的数组上使用时可能会有性能优势,但对于小数组,优势将被初始化数组的成本所包容。 理想情况下,我们会有一个懒惰的稀疏数组,就像在这个[package](https://pypi.python.org/pypi/lazyarray)中实现的数组一样。我没有用过,但可能值得尝试。 –

0

这是另一种方法,无需将循环写入代码即可。在对角平面i == j + k中用True值初始化一个三维数组,并将该矩阵向量乘积与该数组一起使用。

from numpy import * 

def substrings(n, x): 
    A = fromfunction(lambda k, j, i: i == j + k, 
        (len(x) - n + 1, n, len(x))) 
    return A.dot(x) 

这也从一些性能问题受到影响,但您可能能够使其更好地利用SciPy的的稀疏矩阵类,而不是通过numpy的提供密集的一个。

+1

这很聪明!但是,我认为lambda计算或内存分配会减慢速度?这个单线程似乎比np快了3倍。array([x [i:i + n]为范围内的我(len(x)-n + 1)])' – Jezzamon

+0

你找到了最简洁的答案。我认为那也是最快的。 –

0

由于环路放回桌子上:

>>> n = 3 
>>> 
>>> array = ['a', 'b', 'c', 'd', 'e'] 
>>> 
>>> permutations = (array[j:j + n] for j in range(0, len(array) - (n - 1))) 
>>> 
>>> list(permutations) 
[['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']] 

在这个主题上更紧凑的变化:

permutations = (array[j:][0:n] for j in range(len(array) - n + 1)) 
0

我没有(明确的)循环解决方案:

>>> n = 3 
>>> 
>>> array = ['a', 'b', 'c', 'd', 'e'] 
>>> 
>>> permutations = zip(*map(lambda x: array[x:], range(n))) 
>>> 
>>> list(permutations) 
[('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e')] 
>>> 
相关问题