1

我打算教np.einsum给同事们,希望展示如何将其简化为乘法和求和。所以,我想用字母字符代替数字数据。在数组中。

假设我们有 A (2X2) 作为 [['a', 'b'], ['c', 'd']] 和 B (2X1) 作为 [['e'], ['f']] 我们可以使用 einsum 创建一个矩阵 C,比如:np.einsum('ab , bc -> ac', A, B).

我想看到的是:它返回计算图:类似于:a*c + ...等。

当然,np.einsum需要数值数据,如果给定上述代码运行会出错。

4

2 回答 2

2

tensordot有一个使用字符串作为其数组之一的示例,利用'a'*3 => 'aaa'. 但einsum不能对字符串做任何事情(这是编译代码问题)。

前段时间我写了一个纯 python 类似的工作,它解析 'ij,jk->' 字符串,并设置适当的积和计算。这包括额外的调试输出。这可以作为您的任务的起点。

https://github.com/hpaulj/numpy-einsum

最新的einsum做了一些优化,有一些调试帮助。 np.einsum_path提供了更多相关信息。

了解 NumPy 的 einsum

https://en.wikipedia.org/wiki/Einstein_notation

于 2017-06-27T17:34:02.553 回答
1

首先,为什么你需要 B 是 2-dim?为什么不只是np.einsum('ab , b -> a', A, B)

现在是实际的问题:这并不是您想要的,但是通过对 A 和 B 使用明智的选择,您可以使其可见。例如A = [[1,10],[100,1000]]and B = [1,2],它给出了np.einsum('ab , b -> a', A, B) = [21,2100]并且很明显发生了什么。

更通用的版本有点复杂(但希望不是必需的)。这个想法是使用不同的素数势能(特别有用的是 2 和 5,因为它们与 dezimal 系统中容易准备的数字对齐)。如果您想对多个维度求和,您可以考虑取素数(2、3、5、7 等),然后将结果转换为另一个数字系统。如果您对两个昏暗-> 30 进制系统 3 昏暗 (2,3,5,7)-> 210 进制系统求和

于 2017-07-14T12:18:59.167 回答