numpy:高效的选择性多维操作(部分操作)

2024-10-05 10:14:24 发布

您现在位置:Python中文网/ 问答频道 /正文

在numpy中是否有一种方法可以沿某些维度进行部分操作?例如,假设我有两个形状为a=(MxN)、b=(NxK)的矩阵,第三个矩阵我想将a和b的点积存储到其中,例如c=(MxK)。如果我只想要点产品,我可以简单地做:

c = a.dot(b)

现在假设我想用相同的结果填充c,但只部分-例如,仅针对沿M维度的索引0。使用python for循环:

for msel in [0]:
    c[msel,:] = a[msel].dot(b)

或者,例如,将矩阵b添加到矩阵a中,大小为MxN,但仅适用于沿N维的索引0,2:

# Full add would be: a+=b
for nsel in [0,2]:
    a[:,nsel] += b[:,nsel]

抱歉,如果我在这里说得有点含糊,我目前主要需要一个点和加法操作的功能,但我想提出这个问题,希望numpy提供的一些相对通用的东西我不知道

更新:这似乎像预期的那样起作用:

import numpy as np

a = np.array([[0,1,2],
              [3,4,5]])
b = np.array([[0,1],
              [3,4],
              [5,6]])
c = np.zeros((2,2))

#c = a.dot(b)
#for d in [0]:
#  c[d,:] = a[d].dot(b)
cond=[True, False]
c[cond,:] = a[cond,:].dot(b) # <--- what I was searching for for dot
print(c)

a=np.ones((2,3))
b=np.ones((2,3))

#a+=b
#for d in [0,2]:
#  a[:,d] += b[:,d]
cond=[True, False, True]
a[:,cond] += b[:,cond] # <--- what I was searching for for add
print(a)

我想知道幕后(C代码)numpy是否真的只探索了必要的维度,而没有触及其他维度。这太棒了


Tags: innumpyaddfalsetruefornp矩阵
1条回答
网友
1楼 · 发布于 2024-10-05 10:14:24

我是numpy的初学者,有经验的用户可能非常熟悉索引语法。但对于像我这样的初学者,我刚刚确认了上述语法(请参阅相关更新)确实满足了我的需要,而且效率很高。此外,还支持通过布尔掩码和索引列表选择索引

代码段:

import numpy as np
import timeit

a = np.ones((1000, 2000))
b = np.ones((2000, 1000))
c = np.zeros((1000, 1000))

# Prepare dimensions selection (list)
dims=np.arange(0,500,2)
# Prepare dimensions selection (conditions)
cond=np.full((1000), False)
cond[dims] = True

def full_dot(): c = a.dot(b)
def dot_by_dims(): c[dims,:] = a[dims,:].dot(b)
def dot_by_cond(): c[cond,:] = a[cond,:].dot(b)
def dot_by_pyfor():
    for d in dims:
        c[d,:] = a[d,:].dot(b)

print('Full dot time: {} seconds'.format(timeit.Timer(full_dot).timeit(number=100)))
print('Dot partial python for time: {} seconds'.format(timeit.Timer(dot_by_pyfor).timeit(number=100)))
print('Dot partial by dims time: {} seconds'.format(timeit.Timer(dot_by_dims).timeit(number=100)))
print('Dot partial by cond time: {} seconds'.format(timeit.Timer(dot_by_cond).timeit(number=100)))

输出:

Full dot time: 4.831596400000002 seconds
Dot partial python for time: 12.7231105 seconds
Dot partial by dims time: 1.4666931999999946 seconds
Dot partial by cond time: 1.5701424000000017 seconds

(使用经典python for比numpy语法慢8.5倍左右!甚至比完整点慢2.6倍,尽管它只做部分点处理…)

相关问题 更多 >

    热门问题