numpy-最小子数组

numpy-最小子数组,numpy,multidimensional-array,numpy-ndarray,Numpy,Multidimensional Array,Numpy Ndarray,我有一个三维numpyndarray 例如,4x2阵列如下所示: array = [ [ [7 1] [8 0] [2 0] [7 1] ] [ [5 4] [1 4] [6 7] [8 1] ] [ [3 2] [4 5] [8 6] [6 2] ] [ [6 4] [1 2] [5 5] [7 1] ] ] min(nested2 for nested1 in array for nested2 in nested1) 我需要找到一个最小嵌套的最内层数组(有两个数字的数组)及其索

我有一个三维numpy
ndarray

例如,4x2阵列如下所示:

array = [
 [ [7 1] [8 0] [2 0] [7 1] ]
 [ [5 4] [1 4] [6 7] [8 1] ]
 [ [3 2] [4 5] [8 6] [6 2] ]
 [ [6 4] [1 2] [5 5] [7 1] ]
]
min(nested2 for nested1 in array for nested2 in nested1)
我需要找到一个最小嵌套的最内层数组(有两个数字的数组)及其索引,就像Python通常做的那样进行比较:比较第一对元素,如果相等,则比较下一对元素

示例数组的预期结果:
value=[12]
索引=(3,1)

查找元素本身的纯Python代码如下所示:

array = [
 [ [7 1] [8 0] [2 0] [7 1] ]
 [ [5 4] [1 4] [6 7] [8 1] ]
 [ [3 2] [4 5] [8 6] [6 2] ]
 [ [6 4] [1 2] [5 5] [7 1] ]
]
min(nested2 for nested1 in array for nested2 in nested1)

然而,我更喜欢numpy解决方案,因为数组非常庞大……

您想要的行为取决于Python对列表进行词法排序。也就是说,子列表比较如下:

arr1 = np.array(array) # convert your list to numpy array
arr2 = np.sum(arr1,axis=2) # get the sum of the two elements in each array
ind1 = np.unravel_index(arr2.argmin(), arr2.shape) # the indices of the minimum sum
min1 = arr1[ind1] # the value of the minimum array
print(ind1)
(3, 1)
print(min1)
array([1, 2])
In [275]: [1,2]<[2,0]                                                                          
Out[275]: True
让我们试试复杂的路线:

In [291]: x = np.dot(arr, [1,1j])                                                              
In [292]: x                                                                                    
Out[292]: 
array([[7.+1.j, 8.+0.j, 2.+0.j, 7.+1.j],
       [5.+4.j, 1.+4.j, 6.+7.j, 8.+1.j],
       [3.+2.j, 4.+5.j, 8.+6.j, 6.+2.j],
       [6.+4.j, 1.+2.j, 5.+5.j, 7.+1.j]])
In [293]: np.min(x)                                                                            
Out[293]: (1+2j)
In [294]: np.argmin(x)                                                                         
Out[294]: 13
In [295]: np.unravel_index(13, x.shape)                                                        
Out[295]: (3, 1)
一些时间测试:

In [302]: timeit min(nested2 for nested1 in alist for nested2 in nested1)                      
2.24 µs ± 19.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [303]: timeit min(arr.reshape(-1,2).tolist())                                               
2.53 µs ± 13.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [304]: timeit np.min(arr.dot([1,1j]))                                                       
19.5 µs ± 46.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
当阵列大得多时,复杂路由可能会更快,但使用此示例时,复杂路由的性能较差

===

结构化阵列方法:

In [320]: import numpy.lib.recfunctions as rf                                                  
In [321]: rf.unstructured_to_structured(arr, names=['x','y'])                                  
Out[321]: 
array([[(7, 1), (8, 0), (2, 0), (7, 1)],
       [(5, 4), (1, 4), (6, 7), (8, 1)],
       [(3, 2), (4, 5), (8, 6), (6, 2)],
       [(6, 4), (1, 2), (5, 5), (7, 1)]],
      dtype=[('x', '<i8'), ('y', '<i8')])
In [322]: np.argsort(rf.unstructured_to_structured(arr, names=['x','y']).ravel())              
Out[322]: array([13,  5,  2,  8,  9,  4, 14, 11, 12,  6,  0,  3, 15,  1,  7, 10])
In [323]: timeit np.argsort(rf.unstructured_to_structured(arr, names=['x','y']).ravel())       
41.3 µs ± 192 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
[320]中的
:导入numpy.lib.rec函数作为rf
在[321]中:rf.非结构化到结构化(arr,name=['x','y'])
出[321]:
数组([(7,1)、(8,0)、(2,0)、(7,1)],
[(5, 4), (1, 4), (6, 7), (8, 1)],
[(3, 2), (4, 5), (8, 6), (6, 2)],
[(6, 4), (1, 2), (5, 5), (7, 1)]],

dtype=[('x','您想要的行为取决于Python对列表进行词汇排序。也就是说,子列表比较如下:

In [275]: [1,2]<[2,0]                                                                          
Out[275]: True
让我们试试复杂的路线:

In [291]: x = np.dot(arr, [1,1j])                                                              
In [292]: x                                                                                    
Out[292]: 
array([[7.+1.j, 8.+0.j, 2.+0.j, 7.+1.j],
       [5.+4.j, 1.+4.j, 6.+7.j, 8.+1.j],
       [3.+2.j, 4.+5.j, 8.+6.j, 6.+2.j],
       [6.+4.j, 1.+2.j, 5.+5.j, 7.+1.j]])
In [293]: np.min(x)                                                                            
Out[293]: (1+2j)
In [294]: np.argmin(x)                                                                         
Out[294]: 13
In [295]: np.unravel_index(13, x.shape)                                                        
Out[295]: (3, 1)
一些时间测试:

In [302]: timeit min(nested2 for nested1 in alist for nested2 in nested1)                      
2.24 µs ± 19.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [303]: timeit min(arr.reshape(-1,2).tolist())                                               
2.53 µs ± 13.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [304]: timeit np.min(arr.dot([1,1j]))                                                       
19.5 µs ± 46.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
当阵列大得多时,复杂路由可能会更快,但使用此示例时,复杂路由的性能较差

===

结构化阵列方法:

In [320]: import numpy.lib.recfunctions as rf                                                  
In [321]: rf.unstructured_to_structured(arr, names=['x','y'])                                  
Out[321]: 
array([[(7, 1), (8, 0), (2, 0), (7, 1)],
       [(5, 4), (1, 4), (6, 7), (8, 1)],
       [(3, 2), (4, 5), (8, 6), (6, 2)],
       [(6, 4), (1, 2), (5, 5), (7, 1)]],
      dtype=[('x', '<i8'), ('y', '<i8')])
In [322]: np.argsort(rf.unstructured_to_structured(arr, names=['x','y']).ravel())              
Out[322]: array([13,  5,  2,  8,  9,  4, 14, 11, 12,  6,  0,  3, 15,  1,  7, 10])
In [323]: timeit np.argsort(rf.unstructured_to_structured(arr, names=['x','y']).ravel())       
41.3 µs ± 192 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
[320]中的
:导入numpy.lib.rec函数作为rf
在[321]中:rf.非结构化到结构化(arr,name=['x','y'])
出[321]:
数组([(7,1)、(8,0)、(2,0)、(7,1)],
[(5, 4), (1, 4), (6, 7), (8, 1)],
[(3, 2), (4, 5), (8, 6), (6, 2)],
[(6, 4), (1, 2), (5, 5), (7, 1)]],

dtype=[('x',”,不幸的是,没有描述它的作用,但它肯定不能解决问题。相反,它只是使用求和函数减少初始数组的维数。我修复了最小值的代码。如果您的条件是数组“最小和的索引”中两个值的最小和,那么这应该可以工作-由于顺序很重要,您在这里丢失了信息。不幸的是,没有描述它的作用,但它肯定不能解决问题。相反,它只是使用求和函数减少初始数组的维数。我修复了最小值的代码。如果您的条件是a中两个值的最小和,那么这应该可以工作rray“最小和的索引”-由于顺序很重要,您在这里会丢失信息。Python
min
使用的是Python
sort
,对于整数列表来说,它是“词法的”。看起来您是从一个numpy数组开始的,在这种情况下,您的最后一个表达式可能会短到
min(array.reformate(-1,2).tolist()
。也就是说,用数组整形替换嵌套。@hpaulj是的,整形效果很好。但是
.tolist()
每次迭代的平均成本约为5.4秒。其他一切都在100ms以下运行。因此,我希望将繁重的工作转交给numpy…Python
min
使用Python
排序
,对于整数列表来说,排序是“词法的”。看起来您是从一个numpy数组开始的,在这种情况下,您的last表达式可以缩短到
min(array.restrage(-1,2).tolist())
。也就是说,用array restrape替换嵌套。@hpaulj是的,restraping效果很好。但是
.tolist()
每次迭代的平均成本约为5.4秒。其他所有操作的运行时间都在100ms以下。因此,我希望将繁重的工作交给numpy…排序效果很好。排序已经从5.5秒减少到0.3秒,而且我仍然可以避免创建一些中间数组。结构化数组看起来像是我一直缺少的东西!(我以前没有使用过
numpy
).
np.amin
无法使用结构化数组,因为
类型错误:无法使用灵活的类型执行reduce
排序效果很好。已经从5.5s减少到了0.3s,我仍然可以避免创建一些中间数组。结构化数组看起来像是我一直缺少的东西!(我以前没有使用过
numpy
np.amin
无法使用结构化数组,因为
TypeError:无法使用灵活类型执行reduce