在
numpy
中,任何 ndarray
都可以通过指定整数元组来访问。 因此,如果我们构建一个具有任意维度的数组并使用基于元素索引的公式填充它,那么通过提供带有元素索引的元组来访问元素就很简单:
import numpy as np
a = np.zeros((5,4,3,2))
def ivalue(index):
return (index[0]-index[3])/(index[1]+index[2]+1)
for index, _ in np.ndenumerate(a):
a[index] = ivalue(index)
index = (0,3,2,1)
print(a[index]) // -1/6
在
lua
中构造相同的数组相对容易。例如
a = {}
for i=1, 5 do
a[i] = {}
for j=1, 4 do
a[i][j] = {}
for k=1, 3 do
a[i][j][k] = {}
for l=1, 2 do
a[i][j][k][l] = (i-l)/(j+k-1)
end
end
end
end
io.write(a[1][4][3][2]) -- -1/6
但是现在假设我们必须编写一个程序,在给定索引的情况下我们想要返回一个值;在
numpy
中,这很简单,因为(只要 index
与数组结构匹配)我们可以写 a[index]
就完成了。但在 lua
中,我想不出一种方法可以在给定 index={1,4,3,2}
的情况下检索存储的值。 Native python
也有同样的问题,所以我想也许有 lua
的扩展来处理多维数组索引。
我不知道
lua
,但可以给你一个与等效的嵌套Python列表一起使用的函数。
用广播数组制作数组:
In [303]: res = (np.arange(5)[:,None,None,None]-np.arange(2))/(np.arange(4)[:,None,None]+np.arange(3)[:,None]+1)
In [304]: res.shape
Out[304]: (5, 4, 3, 2)
从中创建一个嵌套列表:
In [305]: lres = res.tolist()
In [306]: len(lres), len(lres[0][0])
Out[306]: (5, 3)
应用连续索引的迭代函数:
def foo(a, idx):
res = a
if len(idx)==0:
return res
for i in idx:
res = res[idx[0]]
idx = idx[1:]
return res
使用
index
进行测试:
In [311]: index = (4,3,2,1)
阵列版本:
In [312]: res[index]
Out[312]: 0.5
尝试嵌套列表上的元组:
In [313]: lres[index]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[313], line 1
----> 1 lres[index]
TypeError: list indices must be integers or slices, not tuple
但是功能:
In [314]: foo(lres, index)
Out[314]: 0.5
它也适用于阵列(但速度没那么快):
In [315]: foo(res, index)
Out[315]: 0.5
递归等价:
def foor(a, idx):
if len(idx)==0:
return a
else:
return foor(a[idx[0]], idx[1:])
In [317]: foor(lres, index)
Out[317]: 0.5
从我所看到的一点点来看,
lua
你应该能够毫不费力地翻译其中一个或两个。 看起来它的 table
与 list
类似。
搜索
[lua] array
,SO 上大约有 300 个问题/答案。 因此,人们一直在 lua
中使用某种数组 - 尽管在许多情况下,这可能只是 table
的另一个名称。
在Python中,深度嵌套列表并不常见。 一层嵌套是很常见的。 甚至还有“转置”这样的列表的技巧
In [318]: alist = [[1,2,3],[4,5,6]]; alist
Out[318]: [[1, 2, 3], [4, 5, 6]]
In [319]: list(zip(*alist))
Out[319]: [(1, 4), (2, 5), (3, 6)]
在幕后,
numpy
将所有值存储在平面(1d)数组('C')中,并使用shape
和strides
将其视为多维数组。
创建深度嵌套列表的另一种方法是制作平面列表,并使用一些数学将
index
转换为平面等价物。
numpy 有一个从多维索引计算平面索引的函数:
In [320]: np.ravel_multi_index(index, res.shape)
Out[320]: 119
In [321]: res.ravel()[119]
Out[321]: 0.5
这个方向的计算很容易,反之则有点棘手。
In [324]: res.strides
Out[324]: (192, 48, 16, 8)
In [325]: np.multiply(index, res.strides).sum()/8
Out[325]: 119.0