生成给定大小的n个矩阵(此处为3x2)。我也选择了n = 25,但我让n强调我们拥有的是一堆矩阵的事实。
import numpy as np
n = 25
data = np.random.rand(n, 3, 2)
这只是一个格式示例:我无法更改它。或者如果我这样做,就必须考虑到这种变化的计算成本。
我想以原子方式实现的目标是:
output = []
for datum in data: # This outputs on (3x2) matrix after the other
d0 = datum[0]
dr = datum[1:]
output.append(dr-d0)
或者,以更快的方式:
output = [dr-d0 for (dr, d0) in zip(datum[:,0], datum[:,1:])]
这太慢了:
output = datum[:,1:] - datum[:,0]
不起作用,因为在这种情况下没有很好地定义减法运算的行为。另外,这种切片效率不高。
Cython / Nuitka / PyPy等可能的解决方案,但如果可能的话,我现在想坚持使用原始Numpy。也许某种函数可以非常快速地应用于numpy数组的外部循环元素,而不会产生python的开销......
np.vectorize
功能不起作用:
def get_diff(mat):
return mat[1:] - mat[0]
所以我召唤你们,Numpy的大祭司,Python的仆人来启发我可怜的灵魂!
修改
(我不知道它有名字)
我真正想要做的是确定很多单纯形词的内容(读“音量”)(读作“四面体”)。最简单,最有效的方法是,AFAIK计算:
np.linalg.det(mat[:1]-mat[0])
然后让我重新解释一下我的问题:如何使用普通的python和numpy有效地计算维度k的任何简单集合的内容?
答案 0 :(得分:3)
我建议data[:,1:] - data[:,0,None]
。 None
创建一个新轴(正式你应该使用np.newaxis
,这使得你正在做的很清楚),然后减法将按照你想要的方式运行。< / p>
纠正我认为列表理解中的错误:
def loop(data):
output = []
for datum in data: # This outputs on (3x2) matrix after the other
d0 = datum[0]
dr = datum[1:]
output.append(dr-d0)
return output
def listcomp(data):
output = [dr-d0 for (d0, dr) in zip(data[:,0], data[:,1:])]
return output
def sub(data):
output = data[:,1:] - data[:,0,None]
return output
我们有
>>> import numpy as np
>>> n = 25
>>> data = np.random.rand(n, 3, 2)
>>> res_loop = loop(data)
>>> res_listcomp = listcomp(data)
>>> res_sub = sub(data)
>>> np.allclose(res_loop, res_listcomp)
True
>>> np.allclose(res_loop, res_sub)
True
>>>
>>> %timeit loop(data)
10000 loops, best of 3: 184 µs per loop
>>> %timeit listcomp(data)
10000 loops, best of 3: 158 µs per loop
>>> %timeit sub(data)
100000 loops, best of 3: 12.8 µs per loop