Numpy:从3D数组中减去Numpy argmin

时间:2016-11-08 21:59:14

标签: python arrays numpy

我希望这不是微不足道的,但我似乎无法弄清楚这一点。我想从Numpy数组中减去具有最低平均值的值。我有一个2D案例的解决方案,但我在尝试将其扩展为3D数组时遇到了索引问题

以下是2D阵列工作解决方案的示例:

hdevtools

我实际上是这个2D场景的倍数,每个阵列沿轴堆叠= 2。我想为axis = 2中的每个索引做相同的减法方法,但我意识到它并不像插入不同的轴值那么简单。

我似乎无法超越以下内容,或者当我确实达到不会引发错误的程度时,结果仍然不符合我的预期:

p = np.random.rand(5,4)
p 
Out[19]: array([[ 0.57606498,  0.91115162,  0.99684512,  0.19472954],
       [ 0.40138221,  0.27828228,  0.54265922,  0.34501819],
       [ 0.5818532 ,  0.57426127,  0.34042352,  0.92582929],
       [ 0.52050934,  0.2485581 ,  0.38900122,  0.80904034],
       [ 0.2481113 ,  0.90795755,  0.08984591,  0.87821432]])

# Determine which row has lowest mean value     
np.mean(p,axis=1)
Out[21]: array([ 0.66969782,  0.39183547,  0.60559182,  0.49177725,  0.53103227])

np.argmin(np.mean(p,axis=1))
Out[22]: 1

# Subtract the row with the lowest mean from all rows
p - p[1,:]
Out[23]: 
array([[ 0.17468277,  0.63286934,  0.4541859 , -0.15028865],
       [ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.18047099,  0.29597899, -0.2022357 ,  0.5808111 ],
       [ 0.11912713, -0.02972418, -0.153658  ,  0.46402215],
       [-0.15327091,  0.62967527, -0.45281331,  0.53319613]])

# This is the exact output I was expecting

在没有循环遍历每个索引的情况下,是否有一种优秀而有效的pythonic方法?

更新:较小的3D阵列示例

这是一个3x3x3阵列。切换到p = np.random.rand(5,4,3) p Out[43]: array([[[ 0.23580937, 0.19305653, 0.86194822], [ 0.41709993, 0.44683942, 0.28430556], [ 0.76572705, 0.75579425, 0.79594985], [ 0.685063 , 0.32461701, 0.68805631]], [[ 0.57820915, 0.42726291, 0.11445114], [ 0.73447151, 0.049985 , 0.49230572], [ 0.98135938, 0.43760413, 0.13171786], [ 0.02386192, 0.70637415, 0.19299986]], [[ 0.29256757, 0.30444949, 0.82807243], [ 0.9626889 , 0.83202173, 0.64797922], [ 0.8519458 , 0.77007106, 0.88759858], [ 0.14843446, 0.70316647, 0.13061653]], [[ 0.78799308, 0.55117733, 0.46708366], [ 0.41660748, 0.87715813, 0.42998185], [ 0.70151952, 0.76968747, 0.0307918 ], [ 0.17334519, 0.91885418, 0.52401599]], [[ 0.92093943, 0.41441555, 0.30873481], [ 0.88212707, 0.6201796 , 0.63563756], [ 0.20141727, 0.73164578, 0.70168395], [ 0.26550626, 0.44629422, 0.43902013]]]) minVals = np.argmin(np.mean(p,axis=1),axis=0) # Subtract the values from the original p-p[minVals,:,:] Traceback (most recent call last): File "<ipython-input-45-bcfd1b368acd>", line 1, in <module> p-p[minVals,:,:] ValueError: operands could not be broadcast together with shapes (5,4,3) (3,4,3) 时广播错误消失,但结果不是我所期望的。

axis=2

我希望p = np.random.rand(3,3,3) np.mean(p,axis=2) Out[91]: array([[ 0.45775856, 0.83522052, 0.33993693], [ 0.76745111, 0.74376763, 0.34203944], [ 0.49303518, 0.58334377, 0.42269049]]) np.argmin(np.mean(p,axis=2),axis=0) array([0, 2, 0], dtype=int64) # the second row of the second dataset has the lowest mean and therefore I would expect this this row to be zeros minVals = np.argmin(np.mean(p,axis=2),axis=0) diff = p - p[minVals,:,:] diff Out[95]: array([[[ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ]], [[ 0.62609598, 0.2163244 , -0.0191726 ], [-0.02454002, 0.07961987, 0.42619174], [-0.7446807 , 0.26103203, 0.24169552]], [[-0.06610852, 0.3830212 , -0.21108282], [ 0.21430653, -0.63997565, -0.32996113], [ 0.76924116, -0.36287242, -0.15810806]]]) diff[:,:,0] Out[96]: array([[ 0. , 0. , 0. ], [ 0.62609598, -0.02454002, -0.7446807 ], [-0.06610852, 0.21430653, 0.76924116]]) diff[:,:,1] Out[97]: array([[ 0. , 0. , 0. ], [ 0.2163244 , 0.07961987, 0.26103203], [ 0.3830212 , -0.63997565, -0.36287242]]) diff[:,:,2] Out[98]: array([[ 0. , 0. , 0. ], [-0.0191726 , 0.42619174, 0.24169552], [-0.21108282, -0.32996113, -0.15810806]]) 的第3行为零,因为:

diff[:,:,1]

1 个答案:

答案 0 :(得分:2)

确实,不是那么微不足道,但似乎有效:

p = np.arange(5*4*3).reshape((5, 4, 3))

所以p是:

array([[[ 0,  1,  2],
    [ 3,  4,  5],
    [ 6,  7,  8],
    [ 9, 10, 11]],

   [[12, 13, 14],
    [15, 16, 17],
    [18, 19, 20],
    [21, 22, 23]],

   [[24, 25, 26],
    [27, 28, 29],
    [30, 31, 32],
    [33, 34, 35]],

   [[36, 37, 38],
    [39, 40, 41],
    [42, 43, 44],
    [45, 46, 47]],

   [[48, 49, 50],
    [51, 52, 53],
    [54, 55, 56],
    [57, 58, 59]]])

计算最小行数:

m = np.mean(p, axis=2)
minrows = np.argmin(m, axis=1)
minrows.reshape((-1, 1, 1))
minrows

节目:

array([[[0]],
   [[0]],
   [[0]],
   [[0]],
   [[0]]])

Indexing p with arrays

minidx = np.tile(minrows, (1, p.shape[1], p.shape[2]))
idx = np.indices(p.shape)
p - p[idx[0], minrows, idx[2]]

显示:

array([[[0, 0, 0],
    [3, 3, 3],
    [6, 6, 6],
    [9, 9, 9]],

   [[0, 0, 0],
    [3, 3, 3],
    [6, 6, 6],
    [9, 9, 9]],

   [[0, 0, 0],
    [3, 3, 3],
    [6, 6, 6],
    [9, 9, 9]],

   [[0, 0, 0],
    [3, 3, 3],
    [6, 6, 6],
    [9, 9, 9]],

   [[0, 0, 0],
    [3, 3, 3],
    [6, 6, 6],
    [9, 9, 9]]])

这是预期的答案。