是否可以创建一个看起来像
的数组0, 1, 2, 3, 0, 1, 2, 0, 1, 2, 3, 4, 0, 1
开头有以下数组
4, 3, 5, 2
不使用Python / Numpy中的循环?
修改
这只是一个例子,信息(4,3,5,2)可能有任何长度或数字。
答案 0 :(得分:4)
>>> lengths = np.array([4, 3, 5, 2])
>>> np.concatenate(map(np.arange, lengths))
array([0, 1, 2, 3, 0, 1, 2, 0, 1, 2, 3, 4, 0, 1])
当然,这是作弊,因为map
是伪装的循环。没有NumPy成语可以直接做到这一点,AFAIK。
以上创建了len(lengths)
临时工。不构造这些临时工的替代方案是使用fromiter
和@ jonrsharpe答案的改编版本:
>>> from itertools import chain, imap
>>> np.fromiter(chain.from_iterable(imap(xrange, lengths)), dtype=int,
... count=np.sum(lengths))
array([0, 1, 2, 3, 0, 1, 2, 0, 1, 2, 3, 4, 0, 1])
有些令人惊讶的是,fromiter
成语更快,如果你不先计算计数,会变得更快:
>>> lengths = np.arange(30)
>>> %timeit np.concatenate(map(np.arange, lengths))
10000 loops, best of 3: 64.8 µs per loop
>>> %timeit np.fromiter(chain.from_iterable(imap(xrange, lengths)), dtype=int, count=np.sum(lengths))
10000 loops, best of 3: 28.3 µs per loop
>>> %timeit np.fromiter(chain.from_iterable(imap(xrange, lengths)), dtype=int)
10000 loops, best of 3: 25.8 µs per loop
(运行Linux的x86-64上的NumPy 1.8.1和Python 2.7.6的Timings。)
答案 1 :(得分:2)
你可以在不写for
或while
的情况下完成,但我向你保证,那里有一个循环!
>>> from itertools import chain, imap
>>> list(chain.from_iterable(imap(xrange, (4, 3, 5, 2))))
[0, 1, 2, 3, 0, 1, 2, 0, 1, 2, 3, 4, 0, 1]