Я хотел бы реализовать itertools.combinations для numpy. Основываясь на этом обсуждении, у меня есть функция, которая работает для ввода 1D:
def combs(a, r):
"""
Return successive r-length combinations of elements in the array a.
Should produce the same output as array(list(combinations(a, r))), but
faster.
"""
a = asarray(a)
dt = dtype([('', a.dtype)]*r)
b = fromiter(combinations(a, r), dt)
return b.view(a.dtype).reshape(-1, r)
и вывод имеет смысл:
In [1]: list(combinations([1,2,3], 2))
Out[1]: [(1, 2), (1, 3), (2, 3)]
In [2]: array(list(combinations([1,2,3], 2)))
Out[2]:
array([[1, 2],
[1, 3],
[2, 3]])
In [3]: combs([1,2,3], 2)
Out[3]:
array([[1, 2],
[1, 3],
[2, 3]])
однако было бы лучше, если бы я мог расширить его до N-D входов, где дополнительные размеры просто позволяют вам быстро выполнять несколько вызовов одновременно. Итак, концептуально, если combs([1, 2, 3], 2)
создает [1, 2], [1, 3], [2, 3]
, а combs([4, 5, 6], 2)
создает [4, 5], [4, 6], [5, 6]
, тогда combs((1,2,3) and (4,5,6), 2)
должен создавать [1, 2], [1, 3], [2, 3] and [4, 5], [4, 6], [5, 6]
, где "и" просто представляет собой параллельные строки или столбцы (в зависимости от того, что имеет смысл). (а также для дополнительных измерений)
Я не уверен:
- Как заставить измерения работать логически, что согласуется с тем, как работают другие функции (например, как некоторые функции numpy имеют параметр
axis=
и значение по умолчанию оси 0. Так что, вероятно, ось 0 должна быть той, Комбинируя вместе, а все остальные оси представляют собой параллельные вычисления?) - Как заставить вышеуказанный код работать с ND (сейчас я получаю
ValueError: setting an array element with a sequence.
) - Есть ли лучший способ сделать
dt = dtype([('', a.dtype)]*r)
?