这个算法问题对我来说有点过于复杂:
我有一个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
参数执行它。
答案 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]])