示例:
比方说,数组A具有行a0,a1,a2。 假设数组B的行为b0,b1
六个组合是:
a0-b0,a0-b1,a1-b0, a1-b1,a2-b0,a2-b1
破折号代表串联(np.hstack
)
如何快速处理任意数量的数组(例如,A,B,C,...)?
2个数组的快速方法:Combination of all rows in two numpy arrays
合并3个数组的代码结果:
# input arrays:
[[0 1 2]]
[[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
[[17 18 19 20 21 22 23]
[24 25 26 27 28 29 30]
[31 32 33 34 35 36 37]]
# output:
[[ 0 1 2 5 6 7 8 9 17 18 19 20 21 22 23]
[ 0 1 2 5 6 7 8 9 24 25 26 27 28 29 30]
[ 0 1 2 5 6 7 8 9 31 32 33 34 35 36 37]
[ 0 1 2 10 11 12 13 14 17 18 19 20 21 22 23]
[ 0 1 2 10 11 12 13 14 24 25 26 27 28 29 30]
[ 0 1 2 10 11 12 13 14 31 32 33 34 35 36 37]
[ 0 1 2 15 16 17 18 19 17 18 19 20 21 22 23]
[ 0 1 2 15 16 17 18 19 24 25 26 27 28 29 30]
[ 0 1 2 15 16 17 18 19 31 32 33 34 35 36 37]]
代码:
import numpy as np
def form_combinations(xs):
tot_size = np.sum([x.shape[1] for x in xs])
n_rows = [x.shape[0] for x in xs]
out = np.empty(n_rows + [tot_size])
n_cols = [x.shape[1] for x in xs]
cs = np.cumsum([0] + n_cols)
n = np.newaxis
out[:, :, :, cs[0]:cs[1]] = xs[0][:, n, n, :]
out[:, :, :, cs[1]:cs[2]] = xs[1][n, :, n, :]
out[:, :, :, cs[2]:cs[3]] = xs[2][n, n, :, :]
out = out.reshape(-1, tot_size)
return out
def main():
xs = [
np.arange(3)[np.newaxis, :],
np.arange(5, 20).reshape(3, 5),
np.arange(17, 38).reshape(3, 7)
]
print(xs)
out = form_combinations(xs)
print(out)
main()
答案 0 :(得分:1)
一种方法是使用列表推导,只需在所有三个数组上循环,然后使用df2['Hostname'] = df2['Hostname'].str.replace("*", "")
将它们水平堆叠即可。
hstack
时间
np.array([np.hstack((i, j, k)) for i in a for j in b for k in c])
# array([[ 0, 1, 2, 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23],
# [ 0, 1, 2, 5, 6, 7, 8, 9, 24, 25, 26, 27, 28, 29, 30],
# [ 0, 1, 2, 5, 6, 7, 8, 9, 31, 32, 33, 34, 35, 36, 37],
# [ 0, 1, 2, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23],
# [ 0, 1, 2, 10, 11, 12, 13, 14, 24, 25, 26, 27, 28, 29, 30],
# [ 0, 1, 2, 10, 11, 12, 13, 14, 31, 32, 33, 34, 35, 36, 37],
# [ 0, 1, 2, 15, 16, 17, 18, 19, 17, 18, 19, 20, 21, 22, 23],
# [ 0, 1, 2, 15, 16, 17, 18, 19, 24, 25, 26, 27, 28, 29, 30],
# [ 0, 1, 2, 15, 16, 17, 18, 19, 31, 32, 33, 34, 35, 36, 37]])
答案 1 :(得分:1)
对于任意数量的数组,采用增量方法:
def combine(xs):
comb=np.array([[]],int)
for array in xs:
left = repeat(comb,len(array),axis=0)
right = vstack([array]*len(comb))
comb = hstack((left,right))
return comb
答案 2 :(得分:1)
改编自https://stackoverflow.com/a/49445693/7207392
import numpy as np
import operator as op
import itertools as it
def cartesian_product_pp(arrays, out=None):
la = len(arrays)
h, w = zip(*map(op.attrgetter('shape'), arrays))
w = np.fromiter(it.chain([0], w), int, la+ 1)
W = w.cumsum()
h = *h, W[la]
dtype = np.result_type(*arrays)
arr = np.empty(h, dtype=dtype)
arrs = *it.accumulate(it.chain((arr,), it.repeat(0, la-1)), np.ndarray.__getitem__),
idx = slice(None), *it.repeat(None, la-1)
for i in range(la-1, 0, -1):
arrs[i][..., W[i]:W[i+1]] = arrays[i][idx[:la-i]]
arrs[i-1][1:] = arrs[i]
arr[..., W[0]:W[1]] = arrays[0][idx]
return arr.reshape(-1, W[la])
# example
a = np.r_[:3].reshape(1, 3)
b = np.r_[5:20].reshape(3, 5)
c = np.r_[17:38].reshape(3, 7)
p = cartesian_product_pp([a, b, c])
输出:
>>> p
array([[ 0, 1, 2, 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23],
[ 0, 1, 2, 5, 6, 7, 8, 9, 24, 25, 26, 27, 28, 29, 30],
[ 0, 1, 2, 5, 6, 7, 8, 9, 31, 32, 33, 34, 35, 36, 37],
[ 0, 1, 2, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23],
[ 0, 1, 2, 10, 11, 12, 13, 14, 24, 25, 26, 27, 28, 29, 30],
[ 0, 1, 2, 10, 11, 12, 13, 14, 31, 32, 33, 34, 35, 36, 37],
[ 0, 1, 2, 15, 16, 17, 18, 19, 17, 18, 19, 20, 21, 22, 23],
[ 0, 1, 2, 15, 16, 17, 18, 19, 24, 25, 26, 27, 28, 29, 30],
[ 0, 1, 2, 15, 16, 17, 18, 19, 31, 32, 33, 34, 35, 36, 37]])
@ B.M。和@Bazingaa的方法的时间:
>>> timeit(lambda: cartesian_product_pp([a,b,c]), number=1000)*1000
15.173833002336323
>>> timeit(lambda: combine([a,b,c]), number=1000)*1000
31.1394709860906
>>> timeit(lambda: np.array([np.hstack((i, j, k)) for i in a for j in b for k in c]), number=1000)*1000
51.15771805867553