简体   繁体   English

如何使用numpy生成楼梯编号序列

[英]How to generate staircase number sequence using numpy

I'm trying to generate a list of number sequences using python, like below. 我正在尝试使用python生成一个数字序列列表,如下所示。

[0,0,0,0] [0,0,0,1] [0,0,0,2] [0,0,1,1] [0,0,1,2] [0,0,2,2] [0,1,1,1]
[0,1,1,2] [0,1,2,2] [0,2,2,2] [1,1,1,1] [1,1,1,2] ... [2,2,2,2]

Right now, I can do this using pure python with a recursive call, but it takes a lot of time for a single run (a few hours). 现在,我可以通过递归调用使用纯python来完成此操作,但是单次运行需要花费大量时间(几个小时)。 I wonder if it's possible to do this with numpy and save a huge amount of time, and if yes, how? 我想知道是否可以使用numpy这样做并节省大量时间,如果可以,怎么办?

do you mean this (or how is the sequence you mean defined)? 您的意思是这个(或者您定义的顺序是如何定义的)?

from itertools import product

for item in product((0, 1, 2), repeat=4):
    print(item)

this prints: 打印:

(0, 0, 0, 0)
(0, 0, 0, 1)
(0, 0, 0, 2)
(0, 0, 1, 0)
(0, 0, 1, 1)
(0, 0, 1, 2)
...
(2, 2, 1, 2)
(2, 2, 2, 0)
(2, 2, 2, 1)
(2, 2, 2, 2)

not sure if that is what you are looking for, but product is included in python. 不确定这是否是您要寻找的东西,但是product是否包含在python中。

this should be fast and memory-efficient. 这应该是快速且高效的内存。 the lists are created on demand. 列表是按需创建的。

...on second thought: this is probably what you mean, right? ...再三考虑:这可能就是您的意思,对吧?

for a, b, c, d in product((0, 1, 2), repeat=4):
    if not a <= b <= c <= d:
        continue
    print(a,b,c,d)

with output: 输出:

0 0 0 0, 0 0 0 1, 0 0 0 2, 0 0 1 1, 0 0 1 2, 0 0 2 2, 0 1 1 1, 
0 1 1 2, 0 1 2 2, 0 2 2 2, 1 1 1 1, 1 1 1 2, 1 1 2 2, 1 2 2 2, 
2 2 2 2, 

and now i see how you would want that more efficient... 现在我明白了您将如何想要更高效的...

looks like Praveen's answer provides just that. 看起来Praveen的答案就提供了这一点。

What you're looking for is itertools.combinations_with_replacement . 您正在寻找的是itertools.combinations_with_replacement From the docs: 从文档:

combinations_with_replacement('ABCD', 2) AA AB AC AD BB BC BD CC CD DD

Hence: 因此:

>>> import itertools as it
>>> list(it.combinations_with_replacement((0, 1, 2), 4))
[(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 0, 2),
 (0, 0, 1, 1), (0, 0, 1, 2), (0, 0, 2, 2),
 (0, 1, 1, 1), (0, 1, 1, 2), (0, 1, 2, 2),
 (0, 2, 2, 2), (1, 1, 1, 1), (1, 1, 1, 2),
 (1, 1, 2, 2), (1, 2, 2, 2), (2, 2, 2, 2)]

The best part of this method is that since it returns a generator, you can iterate over it without storing it. 该方法的最好之处在于,由于它返回了生成器,因此可以在不存储它的情况下对其进行迭代。 This is a huge plus, since it'll save you a lot of memory. 这是一个巨大的优势,因为它将节省大量内存。

Other implementations and timing 其他实施方式和时间安排

Here are some more implementations, including a numpy implementation. 这是更多实现,包括numpy实现。 combinations_with_replacement (the try2 function) appears to be the fastest: combinations_with_replacement (该try2函数)似乎是最快的:

import itertools as it
import timeit

import numpy as np

def try1(n, m):
    return [t for t in it.product(range(n), repeat=m) if all(a <= b for a, b in zip(t[:-1], t[1:]))]

def try2(n, m):
    return list(it.combinations_with_replacement(range(n), m))

def try3(n, m):
    a = np.mgrid[(slice(0, n),) * m] # All points in a 3D grid within the given ranges
    a = np.rollaxis(a, 0, m + 1)     # Make the 0th axis into the last axis
    a = a.reshape((-1, m))           # Now you can safely reshape while preserving order
    return a[np.all(a[:, :-1] <= a[:, 1:], axis=1)]

>>> %timeit b = try1(3, 4)
10000 loops, best of 3: 78.1 µs per loop
>>> %timeit b = try2(3, 4)
The slowest run took 8.04 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.66 µs per loop
>>> %timeit b = try3(3, 4)
10000 loops, best of 3: 97.8 µs per loop

This is true even for bigger numbers: 即使是更大的数字也是如此:

>>> %timeit b = try1(3, 6)
1000 loops, best of 3: 654 µs per loop
>>> %timeit b = try2(3, 6)
The slowest run took 7.20 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.33 µs per loop
>>> %timeit b = try3(3, 6)
10000 loops, best of 3: 166 µs per loop

Notes: 笔记:

  • I was using python3 我正在使用python3
  • I used this answer for the implementation of try1 . 我将这个答案用于try1的实现。
  • I used this answer for the implementation of try3 . 我将这个答案用于try3的实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM