Python 两个3d矩阵上的numpy应用函数
所以我想用numpy在两个3d矩阵上应用一个函数,但我不知道怎么做。我读过有关numpy的文章。将_应用于_轴()但无法使其工作 这是我现在的代码:Python 两个3d矩阵上的numpy应用函数,python,numpy,Python,Numpy,所以我想用numpy在两个3d矩阵上应用一个函数,但我不知道怎么做。我读过有关numpy的文章。将_应用于_轴()但无法使其工作 这是我现在的代码: c=np.random.beta(2,3,大小=(2,80)) 定义我的职能(a、b): 席=NP.MatuMl(B,C) SPE=NP幂(A-席,2) 返回spe.sum() a=np.零(形状=(51000,80)) b=np.random.beta(2,3,大小=(51000,2)) np.apply_over_axes(func=my_fu
c=np.random.beta(2,3,大小=(2,80))
定义我的职能(a、b):
席=NP.MatuMl(B,C)
SPE=NP幂(A-席,2)
返回spe.sum()
a=np.零(形状=(51000,80))
b=np.random.beta(2,3,大小=(51000,2))
np.apply_over_axes(func=my_func,a=[a,b],axes=[0,0,0])
它不起作用,而且还回来了
could not broadcast input array from shape (5,1000,80) into shape (5,1000)
我想迭代a
和b
并将my_func
应用于第三维的每个向量
这可以完成工作,但对于正常for循环:
results=[]
对于范围内的i(len(a)):#5次迭代
对于范围内的j(len(a[i]):#1000次迭代
results.append(my_func(a[i][j],b[i][j]))
我想获得这个
结果
但是使用numpy函数。隐藏在np.matmul(b,c)
中的收缩操作可以通过np.tensordot(b,c,axes=[2,0])
实现,其中[2,0]
表示b
中的第三个轴与c
中的第一个轴收缩。也就是说,np.tensordot(b,c,axes=[2,0])。形状是(51000,80)
。从那时起,普通广播适用,您的代码可以归结为
a=np.zero(形状=(5100080))
b=np.random.beta(2,3,size=(51000,2))
c=np.random.beta(2,3,size=(2,80))
席=NP.TunSoRoDOT(B,C,轴= [ 2, 0 ])
SPE=NP幂(A-席,2)
结果2=spe.sum(轴=2)
让我们检查一下,这是否与您通过简单使用循环得到的结果相匹配:
[55]中的:results=np.array(results).重塑(51000)
在[56]中:np.allclose(results,results2)
Out[56]:对
在ipython
会话中运行代码:
In [88]: c = np.random.beta(2,3,size=(2,80))
...:
...: def my_func(a,b):
...: xi = np.matmul(b, c)
...:
...: spe = np.power(a - xi, 2)
...: return spe.sum()
...:
...: a = np.zeros(shape=(5,1000,80))
...: b = np.random.beta(2,3,size=(5,1000,2))
...:
...: np.apply_over_axes(func=my_func,a=[a,b],axes=[0,0,0])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-88-c5e5a66c9d0a> in <module>
10 b = np.random.beta(2,3,size=(5,1000,2))
11
---> 12 np.apply_over_axes(func=my_func,a=[a,b],axes=[0,0,0])
<__array_function__ internals> in apply_over_axes(*args, **kwargs)
/usr/local/lib/python3.6/dist-packages/numpy/lib/shape_base.py in apply_over_axes(func, a, axes)
485
486 """
--> 487 val = asarray(a)
488 N = a.ndim
489 if array(axes).ndim == 0:
/usr/local/lib/python3.6/dist-packages/numpy/core/_asarray.py in asarray(a, dtype, order)
83
84 """
---> 85 return array(a, dtype, copy=False, order=order)
86
87
ValueError: could not broadcast input array from shape (5,1000,80) into shape (5,1000)
a
应该是一个数组,而不是两个数组的列表func
应该采用axis
参数,而不是另一个数组。我不知道你想用[0,0,0]
做什么。对于三维阵列,[0,1]
可能适用,但不能重复0
你的循环
稍微好一点的numpy
风格:
In [91]: results = []
...: for i in range(a.shape[0]): #5 Iterations
...: for j in range(a.shape[1]): #1000 Iterations
...: results.append(my_func(a[i,j], b[i,j]))
...:
In [92]: np.array(results).shape
Out[92]: (5000,)
修改我的函数
要在没有循环的情况下执行此操作,我们需要在myfunc
中使用整个数组函数。没有编译python代码的numpy
apply
——为此,您必须查看numba
或cython
xi=np.matmul(b,c)
<代码>b
is(51000,2),c
is(2,80)matmul
很乐意将b
的最后一个轴与c
的第二个到最后一个轴相结合
In [93]: xi = np.matmul(b,c)
In [94]: xi.shape
Out[94]: (5, 1000, 80)
匹配a
,所以
In [97]: spe = np.power(a-xi,2)
In [98]: spe.shape
Out[98]: (5, 1000, 80)
然后在最后一个轴上求和:
In [99]: res = spe.sum(axis=2)
In [100]: res.shape
Out[100]: (5, 1000)
哪个与您的循环匹配:
In [101]: np.allclose(res.ravel(), np.array(results))
Out[101]: True
除了最后一个sum
,您的myfunc
使用整个数组运行
In [103]: my_func(a,b)
Out[103]: 46883.49325596101
有一个关于这个问题的小例子是很好的,但是你想说什么呢?预期输出是什么?我在原始问题上添加了预期行为,希望现在更清楚。谢谢你的tipThanks;我修正了你的例子,因为它有一些小的语法问题。这有帮助,但还不完全清楚:当您将a[i][j]
作为参数传递给my_func
时,您最终会执行a[i][j][0][0]
,这是不可能的。您能否修复您的示例以使其运行?抱歉,它现在已更新并运行。My_func基本上是一个占位符函数,因此我没有确保它运行:)。现在编写的示例可以归结为results=a[:,:,0]+b[:,:,0]
。这足以解释你需要什么吗?(也就是说,my_func
是否可以通过a[0]
和b[0]
假设只依赖于a
和b[0]
?如果是,我会补充这一点作为答案;如果不是,你能提供一个更接近你需要的例子吗?)
In [101]: np.allclose(res.ravel(), np.array(results))
Out[101]: True
In [103]: my_func(a,b)
Out[103]: 46883.49325596101