Python 外积为弦?

Python 外积为弦?,python,matlab,numpy,Python,Matlab,Numpy,我正在努力做到以下几点。数组[a,b;c,d]与其自身的外积可以描述为长度为2的4x4“字符串”数组。在4x4矩阵的左上角,值是aa、ab、ac、ad。在numpy/python或matlab中生成这些字符串的最佳方法是什么 这只是一个外部产品的示例。目标是处理k个连续的外积,即4x4矩阵可以再次乘以[a,b;c,d]等等。您可以在Python中使用列表理解: 使用itertools和numpy的时髦组合,您可以: >>> from itertools import produ

我正在努力做到以下几点。数组[a,b;c,d]与其自身的外积可以描述为长度为2的4x4“字符串”数组。在4x4矩阵的左上角,值是aa、ab、ac、ad。在numpy/python或matlab中生成这些字符串的最佳方法是什么


这只是一个外部产品的示例。目标是处理k个连续的外积,即4x4矩阵可以再次乘以[a,b;c,d]等等。

您可以在Python中使用列表理解:


使用
itertools
numpy
的时髦组合,您可以:

>>> from itertools import product
>>> s = 'abcd' # s = ['a', 'b', 'c', 'd'] works the same
>>> np.fromiter((a+b for a, b in product(s, s)), dtype='S2',
                count=len(s)*len(s)).reshape(len(s), len(s))
array([['aa', 'ab', 'ac', 'ad'],
       ['ba', 'bb', 'bc', 'bd'],
       ['ca', 'cb', 'cc', 'cd'],
       ['da', 'db', 'dc', 'dd']],
      dtype='|S2')
您还可以通过
itertools
避免使用numpy来获得一些创造性:

>>> from itertools import product, islice
>>> it = (a+b for a, b in product(s, s))
>>> [list(islice(it, len(s))) for j in xrange(len(s))]
[['aa', 'ab', 'ac', 'ad'],
 ['ba', 'bb', 'bc', 'bd'],
 ['ca', 'cb', 'cc', 'cd'],
 ['da', 'db', 'dc', 'dd']]

您可以使用
np.char.array()
以更简单的方式获得@Jaime的结果:

其中:

chararray([['aa', 'ab', 'ac', 'ad'],
       ['ba', 'bb', 'bc', 'bd'],
       ['ca', 'cb', 'cc', 'cd'],
       ['da', 'db', 'dc', 'dd']],
      dtype='|S2')

在Jose Varz回答后继续讨论:

def foo(A,B):
    flatA [x for row in A for x in row],
    flatB = [x for row in B for x in row]
    outer = [[y+x for x in flatA] for y in flatB]
    return outer

In [265]: foo(A,A)
Out[265]: 
[['aa', 'ab', 'ac', 'ad'],
 ['ba', 'bb', 'bc', 'bd'],
 ['ca', 'cb', 'cc', 'cd'],
 ['da', 'db', 'dc', 'dd']]

In [268]: A3=np.array(foo(foo(A,A),A))
In [269]: A3
Out[269]: 
array([['aaa', 'aab', 'aac', 'aad', 'aba', 'abb', 'abc', 'abd', 'aca',
        'acb', 'acc', 'acd', 'ada', 'adb', 'adc', 'add'],
       ['baa', 'bab', 'bac', 'bad', 'bba', 'bbb', 'bbc', 'bbd', 'bca',
        'bcb', 'bcc', 'bcd', 'bda', 'bdb', 'bdc', 'bdd'],
       ['caa', 'cab', 'cac', 'cad', 'cba', 'cbb', 'cbc', 'cbd', 'cca',
        'ccb', 'ccc', 'ccd', 'cda', 'cdb', 'cdc', 'cdd'],
       ['daa', 'dab', 'dac', 'dad', 'dba', 'dbb', 'dbc', 'dbd', 'dca',
        'dcb', 'dcc', 'dcd', 'dda', 'ddb', 'ddc', 'ddd']], 
      dtype='|S3')

In [270]: A3.reshape(4,4,4)
Out[270]: 
array([[['aaa', 'aab', 'aac', 'aad'],
        ['aba', 'abb', 'abc', 'abd'],
        ['aca', 'acb', 'acc', 'acd'],
        ['ada', 'adb', 'adc', 'add']],

       [['baa', 'bab', 'bac', 'bad'],
        ['bba', 'bbb', 'bbc', 'bbd'],
        ['bca', 'bcb', 'bcc', 'bcd'],
        ['bda', 'bdb', 'bdc', 'bdd']],

       [['caa', 'cab', 'cac', 'cad'],
        ['cba', 'cbb', 'cbc', 'cbd'],
        ['cca', 'ccb', 'ccc', 'ccd'],
        ['cda', 'cdb', 'cdc', 'cdd']],

       [['daa', 'dab', 'dac', 'dad'],
        ['dba', 'dbb', 'dbc', 'dbd'],
        ['dca', 'dcb', 'dcc', 'dcd'],
        ['dda', 'ddb', 'ddc', 'ddd']]], 
      dtype='|S3')
根据这个定义,
np.array(foo(A,foo(A,A))).resformate(4,4,4)
生成相同的数组

In [285]: A3.reshape(8,8)
Out[285]: 
array([['aaa', 'aab', 'aac', 'aad', 'aba', 'abb', 'abc', 'abd'],
       ['aca', 'acb', 'acc', 'acd', 'ada', 'adb', 'adc', 'add'],
       ['baa', 'bab', 'bac', 'bad', 'bba', 'bbb', 'bbc', 'bbd'],
       ['bca', 'bcb', 'bcc', 'bcd', 'bda', 'bdb', 'bdc', 'bdd'],
       ['caa', 'cab', 'cac', 'cad', 'cba', 'cbb', 'cbc', 'cbd'],
       ['cca', 'ccb', 'ccc', 'ccd', 'cda', 'cdb', 'cdc', 'cdd'],
       ['daa', 'dab', 'dac', 'dad', 'dba', 'dbb', 'dbc', 'dbd'],
       ['dca', 'dcb', 'dcc', 'dcd', 'dda', 'ddb', 'ddc', 'ddd']], 
      dtype='|S3')

您是否需要两个char.array的Kronecker乘积

快速改编
np.kron
(numpy/lib/shape_base.py):

产生:

A =>

[['a' 'b']
 ['c' 'd']]

outer(A,A) =>

[['aa' 'ab' 'ac' 'ad']
 ['ba' 'bb' 'bc' 'bd']
 ['ca' 'cb' 'cc' 'cd']
 ['da' 'db' 'dc' 'dd']]

kron(A,A) =>

[['aa' 'ab' 'ba' 'bb']
 ['ac' 'ad' 'bc' 'bd']
 ['ca' 'cb' 'da' 'db']
 ['cc' 'cd' 'dc' 'dd']]
kron
通过将
外部元素重塑为
(2,2,2,2)
,然后在
轴=1上串联两次,重新排列
外部元素

kron(kron(A,A),A) =>

[['aaa' 'aab' 'aba' 'abb' 'baa' 'bab' 'bba' 'bbb']
 ['aac' 'aad' 'abc' 'abd' 'bac' 'bad' 'bbc' 'bbd']
 ['aca' 'acb' 'ada' 'adb' 'bca' 'bcb' 'bda' 'bdb']
 ['acc' 'acd' 'adc' 'add' 'bcc' 'bcd' 'bdc' 'bdd']
 ['caa' 'cab' 'cba' 'cbb' 'daa' 'dab' 'dba' 'dbb']
 ['cac' 'cad' 'cbc' 'cbd' 'dac' 'dad' 'dbc' 'dbd']
 ['cca' 'ccb' 'cda' 'cdb' 'dca' 'dcb' 'dda' 'ddb']
 ['ccc' 'ccd' 'cdc' 'cdd' 'dcc' 'dcd' 'ddc' 'ddd']]

kron(kron(kron(A,A),A),A) =>

# (16,16)
[['aaaa' 'aaab' 'aaba' 'aabb'...]
 ['aaac' 'aaad' 'aabc' 'aabd'...]
 ['aaca' 'aacb' 'aada' 'aadb'...]
 ['aacc' 'aacd' 'aadc' 'aadd'...]
 ...]

在Matlab中这很容易,但有一个小问题:数组
['aa''ab']
(例如)与
['aaab']
相同。因此,最终结果将是一个8x4字符数组。或者,结果可以生成一个4x2数组,其中字符串沿第三个dim读取。你希望结果是什么?没关系。您的解决方案是什么?您的(1-D)数组不应该表示为
[a;b;c;D]
而不是
[a,b;c,D]
。您所表示的是一个(2-D)矩阵。正如我所说的,它取决于您希望得到的结果:8x4或4x2。您告诉meTo handler后续产品,将问题定义为2个数组或列表,
foo(A,B)
,其中
A
B
可以有不同的大小(例如4x4和2x4)<代码>foo(foo(A,A),A)
将是连续第二次。谢谢!恐怕这不能推广到更多的外部产品?我编辑了上面的问题。你认为呢?在第二个应用程序中,推广到
[[y+x代表flatA中的x]代表flatB中的y]
会产生一个(16,4)'array'。例如,
[[aaa,aab,aac,aad,aba,…]]
。这就是你想要的吗?是的!几乎,除了(16,4)数组应该是正方形,就像在外部产品中一样,所以它应该被重塑成(8,8)数组。我可以将
(16,4)
重塑成一个有意义的
(4,4,4)
,但不是
(8,8)
[[aaA',aaB',abA',abB baa',bab',bba',bbb'],['aaC'、'aaD'、'abC'、'abD'、'bac'、'bad'、'bbc'、'bbd']、[…]基本上注意,如果你是两个人,请将此列表视为8x8 numpy数组,大写字母会形成块。谢谢,但这不是一个完全的外部产品,答案应该是['aa'、'ab'、'ba'、'bb']、['ac'、'ad'、'bc'、'bd']、['ca'、'cb'、'da'],['cc'、'cd'、'dc'、'dd']]。但是每个字符串中字母的顺序并不重要。很酷!我在
S1
dtype数组上尝试了
np.add.outer(s,s,dtype='S2')
,它返回了
NotImplemented
,已经忘记了这一点。感谢您发布这篇文章!因此基本上重塑了(4,4,4)的每一行将一个2x2的方块排列成一个8x8的阵列。如果这有意义的话。谢谢!但这仍然不太正确。请参阅下面我的评论以了解确切的排列方式。如果你这样做:B=A3.重塑(32,2);C=np.vsplit(B,16),那么每个2x2块都需要排列成一个8x8矩阵。请参阅我的另一个答案-受Kronecker产品启发。
def outer(a,b):
    # custom 'outer' for this issue
    # a,b must be np.char.array for '+' to be defined
    return a.ravel()[:, np.newaxis]+b.ravel()[np.newaxis,:]

def kron(a,b):
    # assume a,b are 2d char array
    # functionally same as np.kron, but using custom outer()
    result = outer(a, b).reshape(a.shape+b.shape)
    result = np.hstack(np.hstack(result))
    result = np.char.array(result)
    return result

A  = np.char.array(list('abcd')).reshape(2,2)
A =>

[['a' 'b']
 ['c' 'd']]

outer(A,A) =>

[['aa' 'ab' 'ac' 'ad']
 ['ba' 'bb' 'bc' 'bd']
 ['ca' 'cb' 'cc' 'cd']
 ['da' 'db' 'dc' 'dd']]

kron(A,A) =>

[['aa' 'ab' 'ba' 'bb']
 ['ac' 'ad' 'bc' 'bd']
 ['ca' 'cb' 'da' 'db']
 ['cc' 'cd' 'dc' 'dd']]
kron(kron(A,A),A) =>

[['aaa' 'aab' 'aba' 'abb' 'baa' 'bab' 'bba' 'bbb']
 ['aac' 'aad' 'abc' 'abd' 'bac' 'bad' 'bbc' 'bbd']
 ['aca' 'acb' 'ada' 'adb' 'bca' 'bcb' 'bda' 'bdb']
 ['acc' 'acd' 'adc' 'add' 'bcc' 'bcd' 'bdc' 'bdd']
 ['caa' 'cab' 'cba' 'cbb' 'daa' 'dab' 'dba' 'dbb']
 ['cac' 'cad' 'cbc' 'cbd' 'dac' 'dad' 'dbc' 'dbd']
 ['cca' 'ccb' 'cda' 'cdb' 'dca' 'dcb' 'dda' 'ddb']
 ['ccc' 'ccd' 'cdc' 'cdd' 'dcc' 'dcd' 'ddc' 'ddd']]

kron(kron(kron(A,A),A),A) =>

# (16,16)
[['aaaa' 'aaab' 'aaba' 'aabb'...]
 ['aaac' 'aaad' 'aabc' 'aabd'...]
 ['aaca' 'aacb' 'aada' 'aadb'...]
 ['aacc' 'aacd' 'aadc' 'aadd'...]
 ...]