Chciałbym wprowadzić itertools.combinations dla numpy. Na podstawie this discussion Mam funkcję, która działa dla wejścia 1D:N-D wersja itertools.combinations w numpy
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)
a wyjście ma sens:
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]])
jednak, że najlepiej byłoby, gdybym mógł rozwinąć go do wejść ND, gdzie dodatkowe wymiary pozwalają tylko na szybkie wykonywanie wielu połączeń naraz. Więc, koncepcyjnie, jeśli combs([1, 2, 3], 2)
wytwarza [1, 2], [1, 3], [2, 3]
i wytwarza [4, 5], [4, 6], [5, 6]
, wówczas combs((1,2,3) and (4,5,6), 2)
powinno wytworzyć [1, 2], [1, 3], [2, 3] and [4, 5], [4, 6], [5, 6]
, gdzie "i" po prostu reprezentuje równoległe wiersze lub kolumny (w zależności od tego, co ma sens). (A także do dodatkowych wymiarów)
nie jestem pewien:
- Jak zrobić wymiary pracować w logiczny sposób, który jest zgodny z okazji pozostałe funkcje działają (jak jak niektóre funkcje NumPy mieć
axis=
Parametr i domyślna oś 0. Tak więc prawdopodobnie oś 0 powinna być tą, którą łączę wzdłuż, a wszystkie inne osie tylko reprezentują obliczenia równoległe?) - Jak uzyskać powyższy kod do pracy z ND (teraz otrzymuję
ValueError: setting an array element with a sequence.
) - Czy jest lepszy sposób na wykonanie
dt = dtype([('', a.dtype)]*r)
?
Więc 'np.dtype ([('', np.intp)] * r)' jest "właściwym" sposobem tworzenia listy typów? Po prostu dźgałem go nożem, aż zadziałało. – endolith
Bardzo fajnie! Zauważyłem, że jest to nieco mniej wydajne (zarówno pod względem szybkości, jak i pamięci) niż rozwiązanie @ HYRY, ale nadal jest lepsze niż po prostu użycie onertools.combinations po wyjęciu z pudełka. –