Python多维数组作为单个列表

时间:2011-01-18 21:47:04

标签: python list multidimensional-array

当然,您可以使用嵌套列表来表示多维数组,但这看起来很昂贵......

[[0, 1], [2, 3]]

是否有某种方法可以将坐标“编码”和“解码”为单个数字,并使用该数字查找相应的元素?

[0, 1, 2, 3]

这需要使用n维,而不仅仅是两个维度,我能想出的最佳编码是:

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 :(得分:3)

您是否因为担心其表现而避免明显的答案(即[[1, 2], [3, 4]])?如果是这样,并且您正在使用numberes,请查看NumPy arrays。最好的解决方案是不要重新发明自己的轮子。

修改 如果你确实觉得有必要按照自己的方式去做,你可以按照像{NumPy这样的strided index scheme进行操作,可能会这样:

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 :(得分: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)

答案 2 :(得分:0)

如果你想要快速数组,你可能希望看到非常快的numpy数组。否则,如果您有尺寸n1,n2,n3,...,nm,那么您可以编码[i] [j] [k] ... [r]:i *((n2,n3 ...的乘积) ))+ j *((n3,n4 ...)的乘积)+ r。你必须得到nm的模块的反向操作,然后你必须减去r并找到nm * n(m-1)的模块,依此类推。

答案 3 :(得分:0)

众所周知的双射:


from itertools import tee

def _basis(dimensions):
    # compute products of subtuple entries
    return tuple(reduce(lambda x,y: x*y, dimensions[:i]) for i in xrange(1, len(dimensions)+1))

def coordinate(n, dimensions):
    basis = _basis(dimensions)
    residues = [n % b for b in basis]
    it2, it1 = tee(basis)
    for x in it2:
        break
    return (residues[0],) + tuple((m2-m1)/b in m2, m1, b in zip(it2, it1, basis))

def number(c, dimensions):
    basis = _basis(dimensions)
    return sum(x*b for x, b in zip(c, basis))