Python Ndaray上的Numpy divide

Python Ndaray上的Numpy divide,python,numpy,multidimensional-array,Python,Numpy,Multidimensional Array,我想创建一个新数组,其中包含另一个数组的比率 第一个简单示例: import numpy as np week = np.full((3, 4), 2, dtype=float) week[:,2] = 0 week[2,0:2] =0 week[0,3] =0.99 week[1,3] =1.99 week[2,3] =0.89 week 返回 array([[2. , 2. , 0. , 0.99], [2. , 2. , 0. , 1.99],

我想创建一个新数组,其中包含另一个数组的比率

第一个简单示例:

import numpy as np
week = np.full((3, 4), 2, dtype=float)
week[:,2] = 0
week[2,0:2] =0
week[0,3] =0.99
week[1,3] =1.99
week[2,3] =0.89

week
返回

array([[2.  , 2.  , 0.  , 0.99],
       [2.  , 2.  , 0.  , 1.99],
       [0.  , 0.  , 0.  , 0.89]])
array([[[[[2.  , 2.  , 0.  , 0.99],
          [2.  , 2.  , 0.  , 1.99],
          [0.  , 0.  , 0.  , 0.89]],

         [[2.  , 2.  , 0.  , 0.99],
          [0.  , 0.  , 0.  , 1.99],
          [2.  , 2.  , 0.  , 0.89]]]]])
现在我想计算一个包含周[:,3]比率的数据数组

ratio =  week[:,3].reshape(1,-1).T/ week[:,3]
返回

array([[1.   , 0.497, 1.112],
       [2.01 , 1.   , 2.236],
       [0.899, 0.447, 1.   ]])
正是我想要的

更一般的情况 一个5d阵列,其中前4个维度可以更改

weeks_5d= np.full((1,1,2, 3, 4), 2, dtype=float)
weeks_5d[:,:,:,:,2] = 0
weeks_5d[:,:,0,2,0:2] =0
weeks_5d[:,:,1,1,0:2] =0
weeks_5d[:,:,:,0,3] = 0.99
weeks_5d[:,:,:,1,3] = 1.99
weeks_5d[:,:,:,2,3] = 0.89

weeks_5d
返回

array([[2.  , 2.  , 0.  , 0.99],
       [2.  , 2.  , 0.  , 1.99],
       [0.  , 0.  , 0.  , 0.89]])
array([[[[[2.  , 2.  , 0.  , 0.99],
          [2.  , 2.  , 0.  , 1.99],
          [0.  , 0.  , 0.  , 0.89]],

         [[2.  , 2.  , 0.  , 0.99],
          [0.  , 0.  , 0.  , 1.99],
          [2.  , 2.  , 0.  , 0.89]]]]])
现在,我想计算每个数据阵列的相同比率

转置5darray会返回奇怪的结果

我需要的是

   array([[[[[1.   , 0.497, 1.112],
              [2.01 , 1.   , 2.236],
              [0.899, 0.447, 1.   ]]],

             [[1.   , 0.497, 1.112],
              [2.01 , 1.   , 2.236],
              [0.899, 0.447, 1.   ]]]]])

我认为在这里,循环是你最大的希望,有一种缓慢和快速的方法:

缓慢的方式:

印刷品

array([[[[[1.        , 0.49748744, 1.11235955],
          [2.01010101, 1.        , 2.23595506],
          [0.8989899 , 0.44723618, 1.        ]],

         [[1.        , 0.49748744, 1.11235955],
          [2.01010101, 1.        , 2.23595506],
          [0.8989899 , 0.44723618, 1.        ]]]]])
array([[[[[1.        , 0.49748744, 1.11235955],
          [2.01010101, 1.        , 2.23595506],
          [0.8989899 , 0.44723618, 1.        ]],

         [[1.        , 0.49748744, 1.11235955],
          [2.01010101, 1.        , 2.23595506],
          [0.8989899 , 0.44723618, 1.        ]]]]])
显然,python中的数组循环速度很慢,但这正是
numba
发明的目的:

快速(呃)方式
来自numba import njit
@njit
def get_比率(arr):
ni,nj,nk=arr.shape[:3]
最后尺寸=阵列形状[3]
新尺寸=np.0(形状=(ni,nj,nk,最后尺寸,最后尺寸),
dtype=np.64)
对于范围内的i(ni):
对于范围内的j(nj):
对于范围内的k(nk):
周=arr[i,j,k,:,3]
对于范围内的d1(最后一个尺寸):
对于范围内的d2(最后一个尺寸):
新协议[i,j,k,d1,d2]=周[d1]/周[d2]
返回新地址
获取比率(周/5d)
印刷品

array([[[[[1.        , 0.49748744, 1.11235955],
          [2.01010101, 1.        , 2.23595506],
          [0.8989899 , 0.44723618, 1.        ]],

         [[1.        , 0.49748744, 1.11235955],
          [2.01010101, 1.        , 2.23595506],
          [0.8989899 , 0.44723618, 1.        ]]]]])
array([[[[[1.        , 0.49748744, 1.11235955],
          [2.01010101, 1.        , 2.23595506],
          [0.8989899 , 0.44723618, 1.        ]],

         [[1.        , 0.49748744, 1.11235955],
          [2.01010101, 1.        , 2.23595506],
          [0.8989899 , 0.44723618, 1.        ]]]]])

对于5d阵列,或者一般来说对于任何形状的阵列,您需要这样做吗?我问的原因是,使用简单的numpy广播规则可能无法实现您想要实现的目标。在这种情况下,您可能必须创建一个新数组,并在其上循环执行基本操作,并用结果填充新数组,这很容易理解为对固定维度集执行操作,但对可变维度集执行操作则更具挑战性这通常适用于5d数组。我也想过做一个循环和堆栈阵列,但可能是性能方面的瓶颈。Thx很多,从来没有听说过numba。多好的包裹啊。我在代码中使用了大量循环+numpy数组。如果我的时间从23µs到1.5µs,使用Nubait这是我最喜欢的软件包,正是出于这些原因,有两件事可以进一步加快此功能。1) 覆盖新数组中的每个值,因此可以分配一个空数组。(
np.zeros
相当于
np.empty
+ndim嵌套循环,用零填充数组)2)您正在检查每个除法的除法为0,这是Python的标准行为,而且可能非常昂贵。您可以通过设置
@njit(error\u model=“numpy”)
sweet来避免这种情况,尽管我知道空的(只是没有想到),但不知道错误模型。谢谢你的提示