#python #python-2.7 #numpy #scikit-learn #itertools
#python #python-2.7 #numpy #scikit-learn #itertools
Вопрос:
Я пытаюсь получить все комбинации с заменой (другими словами, декартовым произведением) строк длиной (8) . Результат слишком большой, и у меня возникают проблемы с одновременным сохранением его в памяти, поэтому мой процесс завершается до его завершения.
Это код, который я использую, который намного быстрее, чем stdlib itertools в Python:
import numpy as np
def cartesian(arrays, out=None):
"""Generate a cartesian product of input arrays.
Parameters
----------
arrays : list of array-like
1-D arrays to form the cartesian product of.
out : ndarray
Array to place the cartesian product in.
Returns
-------
out : ndarray
2-D array of shape (M, len(arrays)) containing cartesian products
formed of input arrays.
Examples
--------
>>> cartesian(([1, 2, 3], [4, 5], [6, 7]))
array([[1, 4, 6],
[1, 4, 7],
[1, 5, 6],
[1, 5, 7],
[2, 4, 6],
[2, 4, 7],
[2, 5, 6],
[2, 5, 7],
[3, 4, 6],
[3, 4, 7],
[3, 5, 6],
[3, 5, 7]])
"""
arrays = [np.asarray(x) for x in arrays]
shape = (len(x) for x in arrays)
dtype = arrays[0].dtype
ix = np.indices(shape)
ix = ix.reshape(len(arrays), -1).T
if out is None:
out = np.empty_like(ix, dtype=dtype)
for n, arr in enumerate(arrays):
out[:, n] = arrays[n][ix[:, n]]
return out
Как бы мне заставить его возвращать генератор из результата, вместо того, чтобы хранить все в памяти сразу?
Комментарии:
1. Вам нужно использовать
yield
оператор для создания функции генератора.
Ответ №1:
Мое впечатление от других вопросов заключается в том, что product
это самый быстрый способ итеративного создания декартовых комбинаций:
In [494]: g=itertools.product([1,2,3],[4,5],[6,7])
In [495]: list(g)
Out[495]:
[(1, 4, 6),
(1, 4, 7),
(1, 5, 6),
(1, 5, 7),
(2, 4, 6),
(2, 4, 7),
(2, 5, 6),
(2, 5, 7),
(3, 4, 6),
(3, 4, 7),
(3, 5, 6),
(3, 5, 7)]
Ваш код представляет собой отображение np.indices
, которое работает медленнее:
In [499]: timeit np.indices((3,2,2)).reshape(3,-1).T
The slowest run took 11.08 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 61.6 µs per loop
In [500]: timeit list(itertools.product([1,2,3],[4,5],[6,7]))
100000 loops, best of 3: 3.51 µs per loop