То, что вы хотите, является внешним продуктом.
Просто для удовольствия, я буду придерживаться ваших строк, но создам object
массивы dtype:
In [677]: v = np.array([ ['x1','y1','z1'], ['x2','y2','z2'] ],object)
In [678]: v
Out[678]:
array([['x1', 'y1', 'z1'],
['x2', 'y2', 'z2']], dtype=object)
In [679]: b = np.array([ ['t1','c1'], ['t2','c2'] ] ,object)
In [680]: v.shape
Out[680]: (2, 3)
In [681]: b.shape
Out[681]: (2, 2)
Тогдаесли я использую broadcasting
и plus
(что для строк равно join
), я получаю:
In [683]: v[None,:,:]+b[:,:,None]
Out[683]:
array([[['x1t1', 'y1t1', 'z1t1'],
['x2c1', 'y2c1', 'z2c1']],
[['x1t2', 'y1t2', 'z1t2'],
['x2c2', 'y2c2', 'z2c2']]], dtype=object)
Это умножает массив (2,3) на (2,2), расширяяих для (1,2,3) и (2,2,1) => (2,2,3)
То же самое, но с числовыми массивами, что позволяет мне использовать + или *:
In [684]: V = np.arange(10,70,10).reshape(2,3)
In [685]: B = np.arange(1,5).reshape(2,2)
In [686]: V[None,:,:]+B[:,:,None]
Out[686]:
array([[[11, 21, 31],
[42, 52, 62]],
[[13, 23, 33],
[44, 54, 64]]])
In [687]: V[None,:,:]*B[:,:,None]
Out[687]:
array([[[ 10, 20, 30],
[ 80, 100, 120]],
[[ 30, 60, 90],
[160, 200, 240]]])
Ваш код цикла не совсем тот же (те же комбинации, но разной формы)
In [697]: out = []
...: for i in b:
...: for h in range(2):
...: out.append(v[h] + i[h])
...: np.array(out)
Out[697]:
array([['x1t1', 'y1t1', 'z1t1'],
['x2c1', 'y2c1', 'z2c1'],
['x1t2', 'y1t2', 'z1t2'],
['x2c2', 'y2c2', 'z2c2']], dtype=object)
In [699]: out = []
...: for i in B:
...: for h in range(2):
...: out.append(V[h] * i[h])
...: np.array(out)
Out[699]:
array([[ 10, 20, 30],
[ 80, 100, 120],
[ 30, 60, 90],
[160, 200, 240]])
einsum
- еще один способ выразить этикомбинации:
In [708]: np.einsum('ij,jk->ijk',B,V)
Out[708]:
array([[[ 10, 20, 30],
[ 80, 100, 120]],
[[ 30, 60, 90],
[160, 200, 240]]])
Если я скажу это для суммирования измерения j
, я получу матричный продукт, np.dot(B,V)
:
In [709]: np.einsum('ij,jk->ik',B,V)
Out[709]:
array([[ 90, 120, 150],
[190, 260, 330]])