Python 两个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

所以我想用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_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