python 速度矢量_python – 用numpy进行矢量操作

我有三个numpy数组:

X:3073 x 49000矩阵

W:10×3073矩阵

y:49000 x 1向量

y包含0到9之间的值,每个值表示W中的一行.

我想将第一列X添加到y中第一个元素给出的W行中.即如果y中的第一个元素是3,则将X的第一列添加到W的第四行.然后将第二列X添加到y中第二个元素给出的W中的行,依此类推,直到所有列为X已经被y指定为W中的行,这意味着总共添加了49000行.

W [y] = X.T对我不起作用,因为这不会在W中的一行中添加多个向量.

请注意:我只是在寻找矢量化解决方案.即没有for循环.

编辑:为了澄清我将添加一个小矩阵大小的例子改编自萨尔瓦多达利的例子如下.

In [1]: import numpy as np

In [2]: a, b, c = 3, 4, 5

In [3]: np.random.seed(0)

In [4]: X = np.random.randint(10, size=(b,c))

In [5]: W = np.random.randint(10, size=(a,b))

In [6]: y = np.random.randint(a, size=(c,1))

In [7]: X

Out[7]:

array([[5, 0, 3, 3, 7],

[9, 3, 5, 2, 4],

[7, 6, 8, 8, 1],

[6, 7, 7, 8, 1]])

In [8]: W

Out[8]:

array([[5, 9, 8, 9],

[4, 3, 0, 3],

[5, 0, 2, 3]])

In [9]: y

Out[9]:

array([[0],

[1],

[1],

[2],

[0]])

In [10]: W[y.ravel()] + X.T

Out[10]:

array([[10, 18, 15, 15],

[ 4, 6, 6, 10],

[ 7, 8, 8, 10],

[ 8, 2, 10, 11],

[12, 13, 9, 10]])

In [11]: W[y.ravel()] = W[y.ravel()] + X.T

In [12]: W

Out[12]:

array([[12, 13, 9, 10],

[ 7, 8, 8, 10],

[ 8, 2, 10, 11]])

问题是将W中的BOTH第0列和第4列添加到W中的第0行,以及将X中的第1列和第2列添加到W中的第1行.

因此,期望的结果是:

W = [[17, 22, 16, 16],

[ 7, 11, 14, 17],

[ 8, 2, 10, 11]]

最佳答案 首先是直接循环解决方案作为参考:

In [65]: for i,j in enumerate(y):

W[j]+=X[:,i]

....:

In [66]: W

Out[66]:

array([[17, 22, 16, 16],

[ 7, 11, 14, 17],

[ 8, 2, 10, 11]])

一个add.at解决方案:

In [67]: W=W1.copy()

In [68]: np.add.at(W,(y.ravel()),X.T)

In [69]: W

Out[69]:

array([[17, 22, 16, 16],

[ 7, 11, 14, 17],

[ 8, 2, 10, 11]])

add.at执行无缓冲计算,绕过阻止W [y.ravel()] = X.T工作的缓冲.它仍然是迭代的,但循环已经移动到编译代码.这不是真正的矢量化,因为应用程序的顺序很重要.一行X.T的添加取决于前一行的结果.

但是在处理大型数组时:

X: a 3073 x 49000 matrix

W: a 10 x 3073 matrix

y: a 49000 x 1 vector

这可能会遇到速度问题.请注意,W [y.ravel()]的大小与X.T相同(为什么选择这些需要转置的大小?).这是一个副本,而不是一个视图.所以已经有时间惩罚了.

在之前的问题中已经提出了bincount,我认为它更快. Making for loop with index arrays faster(bincount和add.at解决方案)

迭代小的3073尺寸也可以具有速度优势.或者更好的是尺寸10维度,如Divakar所示.

对于小测试用例,a,b,c = 3,4,5,add.at解决方案最快,其次是Divakar的bincount和einseum.对于较大的a,b,c = 10,1000,20000,add.at变得非常慢,bincount是最快的.

相关的答案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值