将Python多维数组作为单个列表
当然,你可以用嵌套列表来表示多维数组,但这样做似乎会消耗很多资源...
[[0, 1], [2, 3]]
有没有什么方法可以把坐标“编码”和“解码”成一个数字,然后用这个数字来查找对应的元素呢?
[0, 1, 2, 3]
这个方法需要适用于多维的情况,不仅仅是二维的。我想到的编码方法是:
def getcellindex(self, location):
cindex = 0
cdrop = self.gridsize # where self.gridsize is the number of cells
for index in xrange(self.numdimensions): # where self.numdimensions is the number of dimensions
# where self.dimensions is a tuple of the different sizes of the corresponding dimension
cdrop /= self.dimensions[index]
cindex += cdrop * location[index]
return cindex
可能还有其他优化的方法,但更重要的是,我该如何逆向这个过程呢?这个函数能正常工作吗?
4 个回答
0
如果你想要快速的数组,可以看看numpy数组,它们的速度非常快。否则,如果你有多个维度,比如n1, n2, n3, ..., nm,那么你可以用一个公式来表示数组中的元素,比如a[i][j][k]...[r]。这个公式是:i乘以(n2, n3, ...)的乘积,加上j乘以(n3, n4, ...)的乘积,再加上r。要反向操作,你需要对nm取模,这样就能得到r。然后你要减去r,再对nm乘以n(m-1)取模,依此类推。
3
你是不是因为担心性能问题而避开了明显的答案(比如 [[1, 2], [3, 4]]
)?如果是这样,而且你是在处理数字的话,可以看看NumPy数组。最好的办法就是别自己重新发明轮子。
编辑:如果你真的想按照自己的方式来做,可以参考NumPy的分步索引方案,大概可以这样做:
import operator
def product(lst):
return reduce(operator.mul, lst, 1)
class MyArray(object):
def __init__(self, shape, initval):
self.shape = shape
self.strides = [ product(shape[i+1:]) for i in xrange(len(shape)) ]
self.data = [initval] * product(shape)
def getindex(self, loc):
return sum([ x*y for x, y in zip(self.strides, loc) ])
def getloc(self, index):
loc = tuple()
for s in self.strides:
i = index // s
index = index % s
loc += (i,)
return loc
可以这样使用:
arr = MyArray((3, 2), 0)
arr.getindex((2, 1))
-> 5
arr.getloc(5)
-> (2, 1)
1
def getlocation(self, cellindex):
res = []
for size in reversed(self.dimensions):
res.append(cellindex % size)
cellindex /= size
return res[::-1]
class ndim:
def __init__(self):
self.dimensions=[8,9,10]
self.numdimensions=3
self.gridsize=8*9*10
def getcellindex(self, location):
cindex = 0
cdrop = self.gridsize
for index in xrange(self.numdimensions):
cdrop /= self.dimensions[index]
cindex += cdrop * location[index]
return cindex
def getlocation(self, cellindex):
res = []
for size in reversed(self.dimensions):
res.append(cellindex % size)
cellindex /= size
return res[::-1]
n=ndim()
print n.getcellindex((0,0,0))
print n.getcellindex((0,0,1))
print n.getcellindex((0,1,0))
print n.getcellindex((1,0,0))
print n.getlocation(90)
print n.getlocation(10)
print n.getlocation(1)
print n.getlocation(0)
或者,查看完整的测试案例