通过索引和将NumPy数组的元素分组

时间:2020-03-22 14:44:07

标签: python arrays numpy

我有几个尺寸为30 * 30 * 30的大型numpy数组,我需要在该数组上遍历该数组,获取每个索引三元组的总和,然后以该总和将这些元素归类。例如,考虑以下简单的2 * 2数组:

test = np.array([[2,3],[0,1]])

此数组的索引为[0,0],[0,1],[1,0]和[1,1]。该例程将返回列表:[2,[3,0],1],因为数组 test 中的2的索引总和为0,3和0的索引总和为1,1的索引总和为2。我知道遍历NumPy数组并检查和的蛮力方法是可行的,但是对于我的N(= 30)大和几个数组的实际情况来说,效率太低了。使用NumPy例程完成此分组的任何输入将不胜感激。预先谢谢你。

2 个答案:

答案 0 :(得分:3)

这是应该相当快但不是超级快的一种方法:30x30x30在我的计算机上占用了20 ms

import numpy as np

# make example
dims = 2,3,4
a = np.arange(np.prod(dims),0,-1).reshape(dims)

# create and sort indices
idx = sum(np.ogrid[tuple(map(slice,dims))])
srt = idx.ravel().argsort(kind='stable')

# use order to arrange and split data
asrt = a.ravel()[srt]
spltpts = idx.ravel().searchsorted(np.arange(1,np.sum(dims)-len(dims)+1),sorter=srt)
out = np.split(asrt,spltpts)

# admire
out
# [array([24]), array([23, 20, 12]), array([22, 19, 16, 11,  8]), array([21, 18, 15, 10,  7,  4]), array([17, 14,  9,  6,  3]), array([13,  5,  2]), array([1])]

答案 1 :(得分:1)

您可以在过程上创建索引连音符的列表并使用它,但是可能会陷入太大而无法有效的代码常量中。 [(0,0),[(1,0),(0,1)],(1,1)],

因此,您需要一个函数来为n维数组动态生成这些索引。

对于一维,微不足道的计数/增量

   [(0),(1),(2),...] 

第二个,对第一个维度使用一维策略,第一个递减,第二个递增以填充。

   [(0...)...,(1...)...,(2...)...,...] 
   [[(0,0)],[(1,0),(0,1)],[(2,0),(1,1),(0,2)],[...],...]

请注意,其中一些将不在示例数组之内,您的生成器将需要包括边界检查。

然后在三个维度上,对前两个维度进行上述处理,但是最后,减小第一个维度,增大第三个维度,直到完成

[[(0,0,0),...],[(1,0,0),(0,1,0),...],[(2,0,0),(1,1,0),(0,2,0),...],[...],...]
[[(0,0,0)],[(1,0,0),(0,1,0),(0,0,1)],[(2,0,0),(1,1,0),(0,2,0),(1,0,1),(0,1,1)(0,0,2)

再次需要进行边界检查或更聪明的起点/终点,以避免尝试在索引之外进行访问,但是这种通用算法是您如何动态生成索引的方法,而不是让两个大型数组竞争缓存和/ o。

作为练习,留给用户来生成python或nympy等效项。