numpy-最小子数组
我有一个三维numpynumpy-最小子数组,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) 我需要找到一个最小嵌套的最内层数组(有两个数字的数组)及其索
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“最小和的索引”-由于顺序很重要,您在这里会丢失信息。Pythonmin
使用的是Pythonsort
,对于整数列表来说,它是“词法的”。看起来您是从一个numpy数组开始的,在这种情况下,您的最后一个表达式可能会短到min(array.reformate(-1,2).tolist()
。也就是说,用数组整形替换嵌套。@hpaulj是的,整形效果很好。但是.tolist()
每次迭代的平均成本约为5.4秒。其他一切都在100ms以下运行。因此,我希望将繁重的工作转交给numpy…Pythonmin
使用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