her*_*uzz 5 python numpy numpy-ndarray
我有一个矩阵x,其3 x 3维度和向量w是3,:
x = np.array([[1, 2, 1],
[3, 2 ,1],
[1, 2, 2]])
w = np.array([0.3, 0.4, 0.3])
Run Code Online (Sandbox Code Playgroud)
我需要生成另一个向量y,该向量对 x. 的每一列x由 中的相应值加权w。像这样的东西:
for y[0],它应该寻找X[0] => [1, 2, 1]
对w按其在 X 中的值分组的列的权重 (in )求和:
0.3 + 0.3 = 0.60.40由于值为 1 的列的权重总和最高,因此y[0] = 1. 等等。
如果您了解广播,则可以使用 numpy 来完成。缺点是,由于代码是矢量化的,因此您执行的计算量会超出您的需要。如果向量的大小w非常大,这会很重要。
也许有人想出了一种更简单的方法来编写它,但这就是我不会考虑太多的方式。
先回答一下:
i = np.arange(3) + 1
m = (x.reshape((1,4,3)) == i.reshape((3,1,1)))
np.argmax(np.sum(m, axis=2).T*w, axis=1) + 1
Run Code Online (Sandbox Code Playgroud)
现在逐步解释...请注意,通常最好从零开始计数,但我遵循了您的约定。
我添加了一行,因此数组不对称(更容易检查形状)
In [1]: x = np.array([[1, 2, 1],
...: [3, 2 ,1],
...: [1, 2, 2],
...: [3, 1, 3]])
...:
...: w = np.array([0.3, 0.4, 0.3])
Run Code Online (Sandbox Code Playgroud)
第一步是获得索引数组i。您的会议从一开始。
In [2]: i = np.arange(3) + 1
Run Code Online (Sandbox Code Playgroud)
棘手的步骤:创建一个形状为 (3,4,3) 的数组,其中数组的第 i 个条目是一个 (4,3) 数组,所有条目都是 0 或 1。当且仅当 x = = i. 这是通过添加维度来完成的x,i因此它们可以被广播。x该操作基本上比较和的所有组合i,因为x匹配大小的所有维度=1 维度i,反之亦然:
In [3]: m = (x.reshape((1,4,3)) == i.reshape((3,1,1)))*1
In [4]: m
Out[4]:
array([[[1, 0, 1],
[0, 0, 1],
[1, 0, 0],
[0, 1, 0]],
[[0, 1, 0],
[0, 1, 0],
[0, 1, 1],
[0, 0, 0]],
[[0, 0, 0],
[1, 0, 0],
[0, 0, 0],
[1, 0, 1]]])
Run Code Online (Sandbox Code Playgroud)
现在,您沿行求和(即 axis=2),以获得每个选择出现在每行中的次数x(请注意,当您将其与 进行比较时,结果会被转置x):
In [5]: np.sum(m, axis=2)
Out[5]:
array([[2, 1, 1, 1],
[1, 1, 2, 0],
[0, 1, 0, 2]])
Run Code Online (Sandbox Code Playgroud)
我希望你已经知道事情的发展方向了。可以直接读:在第一行中x,1出现了两次,2出现了一次。在 的第二行中x, 全部出现一次,在 的第三行中x,1出现一次,2出现两次,以此类推。
将其乘以权重:
In [7]: np.sum(m, axis=2).T*w
Out[7]:
array([[0.6, 0.4, 0. ],
[0.3, 0.4, 0.3],
[0.3, 0.8, 0. ],
[0.3, 0. , 0.6]])
Run Code Online (Sandbox Code Playgroud)
获取沿行的最大值(添加一个以符合您的约定):
In [8]: np.argmax(np.sum(m, axis=2).T*w, axis=1) + 1
Out[8]: array([1, 2, 2, 3])
Run Code Online (Sandbox Code Playgroud)
特殊情况:领带
评论中提到了以下案例:
x = np.array([[2, 2, 4, 1]])
w = np.array([0.1, 0.2, 0.3, 0.4])
Run Code Online (Sandbox Code Playgroud)
权重之和为:
[0.1, 0.4, 0., 0.4]
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下没有赢家。从这个问题来看,并不清楚在这种情况下人们会做什么。可以全取,也可以全取……可以在最后查找这些案例:
final_w = np.sum(m, axis=2).T*w
result = np.argmax(np.sum(m*w, axis=2), axis=0) + 1
special_cases = np.argwhere(np.sum(final_w == np.max(final_w), axis=1) > 1)
Run Code Online (Sandbox Code Playgroud)
注意:为了可读性,我使用了 reshape 方法,但我经常使用np.expand_dims或 np.newaxis。像这样的东西:
i = np.arange(3) + 1
m = (x[np.newaxis] == i[:, np.newaxis, np.newaxis])
np.argmax(np.sum(m, axis=2).T*w, axis=1) + 1
Run Code Online (Sandbox Code Playgroud)
另一种选择:您还可以使用某种编译代码。例如,numba 在这种情况下非常容易使用。
| 归档时间: |
|
| 查看次数: |
156 次 |
| 最近记录: |