通过内部数据索引和顺序访问数组元素

时间:2015-06-29 18:13:31

标签: python arrays algorithm numpy

这个算法问题对我来说有点过于复杂:

我有一个NumPy数据数组,它以一种特殊的方式在内部编入索引。数据是拼接在一起的两个阵列的输出(我没有),具有不同的排序。我将参数max设置为正整数,数据输出的索引格式为

[ 00 10 20 ... max0 11 12 ... max1 22 23....max2 33....max max ]

参数max确定数组的输出(即数组的长度)和排序。

对于几个示例,对于max=2,数据的顺序为

[00 10 20 11 21 22]

设置max=3给出

[00 10 20 30 11 21 31 22 32 33]

max=4

[00 10 20 30 40 11 21 31 41 22 32 42 33 43 44]

等等。

我想写一个算法来制作只有3x值的列表/数组,即带有第一个索引3的值。也就是说,我只想访问某些数据值,由第一个索引组织。

但是,这由参数max决定。如您所见,这决定了数组索引放置数据的位置。我唯一的想法是制作某种排序树,但我不知道如何用这个max参数执行它。

1 个答案:

答案 0 :(得分:0)

此列表理解(或迭代)生成您显示的索引

[[j*10+i for j in range(i,max+1)] for i in range(max+1)]

max=2: [[0, 10, 20], [11, 21], [22]]
max=3: [[0, 10, 20, 30], [11, 21, 31], [22, 32], [33]]
max=4: [[0, 10, 20, 30, 40], [11, 21, 31, 41], [22, 32, 42], [33, 43], [44]]

这些列表列表可以展平。但这种安排可能会让人更容易思考这个问题。

或者生成元组更有用:

In [134]: [[(j,i) for j in range(i,max+1)] for i in range(max+1)]
Out[134]: 
[[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)],
 [(1, 1), (2, 1), (3, 1), (4, 1)],
 [(2, 2), (3, 2), (4, 2)],
 [(3, 3), (4, 3)],
 [(4, 4)]]

目前还不清楚你想对这些数字或索引做什么,但这里有一个将它们放在二维数组中的例子:

In [150]: dlist=[[j*10+i for j in range(i,max+1)] for i in range(max+1)]
In [151]: ilist=[[(j,i) for j in range(i,max+1)] for i in range(max+1)]

In [152]: import itertools

In [155]: M=np.zeros((max+1,max+1),int)
In [157]: for (i,j),d in zip(itertools.chain(*ilist),itertools.chain(*dlist)):
    M[i,j]=d

In [158]: M
Out[158]: 
array([[ 0,  0,  0,  0,  0],
       [10, 11,  0,  0,  0],
       [20, 21, 22,  0,  0],
       [30, 31, 32, 33,  0],
       [40, 41, 42, 43, 44]])

前5个数字在第1列,第2个4在下一个,等等。

itertools.chain是展平列表列表的一种方式。

M的布局看起来像一个较低的三角形。有numpy函数来生成这些索引:

In [176]: np.tril_indices(5)
Out[176]: 
(array([0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4], dtype=int32),
 array([0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4], dtype=int32))

所以我可以填充M

data =  np.dot([10,1],np.tril_indices(5))
M[np.tril_indices(5)] = data

深入研究tril_indices的代码我发现起点是由1生成的掩码:

I=((np.arange(max)-np.arange(max)[:,None])<0).astype(int)
array([[0, 0, 0, 0],
       [1, 0, 0, 0],
       [1, 1, 0, 0],
       [1, 1, 1, 0]])