Reputation: 167
I know that itertools.combinations will iterate through all combinations of a certain length from an iterable:
import itertools
import numpy as np
my_array = np.array([[0,1,2],[3,4,5],[6,7,8]])
for c in itertools.combinations(my_array, 2):
print (c)
Would print
(array([0, 1, 2]), array([3, 4, 5]))
(array([0, 1, 2]), array([6, 7, 8]))
(array([3, 4, 5]), array([6, 7, 8]))
However, I want something like
for c, d in combo_splits(my_array, 2):
print (c)
print (d)
To print
(array([0, 1, 2]), array([3, 4, 5]))
array([4, 5, 6])
(array([0, 1, 2]), array([6, 7, 8]))
array([3, 4, 5])
(array([3, 4, 5]), array([6, 7, 8]))
array([0, 2, 3])
Upvotes: 0
Views: 164
Reputation: 362796
I would use combinations to generate a mask instead, and then just use the mask to fancy-index your array. That would look like this:
import itertools
import numpy as np
my_array = np.array([[0,1,2],[3,4,5],[6,7,8]])
n = len(my_array)
for r in itertools.combinations(xrange(n), 2):
rows = np.array(r)
on = np.zeros(n, dtype=bool)
on[rows] = True
print my_array[on]
print my_array[~on]
Upvotes: 1
Reputation: 280993
This doesn't come with Python, but you can build it on top of itertools.combinations
fairly easily:
def combinations_with_leftovers(pool, k):
"""itertools.combinations, but also returning the parts we didn't take.
Each element of combinations_with_leftovers(pool, k) is a tuple (a, b)
where a is the tuple that itertools.combinations would have given
and b is a tuple of the elements of pool not used in a.
"""
pool = tuple(pool)
for chosen_indices in itertools.combinations(xrange(len(pool)), k):
chosen_indices = set(chosen_indices)
a = tuple(x for i, x in enumerate(pool) if i in chosen_indices)
b = tuple(x for i, x in enumerate(pool) if i not in chosen_indices)
yield a, b
Upvotes: 0