【问题标题】:Accessing array elements by internal data index and order通过内部数据索引和顺序访问数组元素
【发布时间】:2015-06-29 18:13:30
【问题描述】:

这个算法问题对我来说有点太复杂了:

我有一个 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 参数执行它。

【问题讨论】:

  • 我看到的唯一模式是[(00 10 20 30 40)(11 21 31 41)(22 32)(33 43)(44)],即(每组中的元素数)[(max-0)(max-1)(max-2)(max-3)...(max-n)] where n <= max 每组比最后一组多11,每组中的每个数字都偏移10。我看到的唯一问题是没有数字可以超过 'max*11' 但这并不能解释为什么第二组(零索引)中没有 42。也许有人可以以此为起点。这是我得到的最佳答案
  • @SirParselot 抱歉,有错字。应该有一个42

标签: python arrays algorithm numpy


【解决方案1】:

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

[[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 个数字在第一列,第二个 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的代码,发现起点是一个1s的掩码,由:

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]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2018-12-09
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2019-07-28
    相关资源
    最近更新 更多