2011-01-18 62 views
1

當然,你可以有嵌套表來表示多維數組,但似乎昂貴...Python的多維數組作爲一個單一的列表

[[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 

有很可能的方式來優化這一點,但更重要的是,我該如何扭轉這一過程?而且,這個功能是否有效?

+2

「似乎昂貴」?這只是過早的優化? – FogleBird 2011-01-18 21:53:00

+0

任何理由不使用numpy? – 2011-01-18 22:04:27

回答

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

你避免的,因爲關於它的性能問題顯而易見的答案(即[[1, 2], [3, 4]])?如果是這樣,你正在使用numberes,請看NumPy arrays。最好的解決辦法是不要重新發明自己的車輪。

編輯: 如果你覺得有必要做它自己的方式,你可以遵循strided index scheme像NumPy這樣,wihch可能會去是這樣的:

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

如果你想快速的數組,你可能想看到numpy數組,這是非常快的。否則,如果你有尺寸n1,n2,n3,...,nm,那麼你可以編碼一個[i] [j] [k] ... [r]:i *((n2,n3 ... ))+ j *((n3,n4 ...))+ r的乘積。反向操作你必須得到nm的模塊,這將是r,那麼你必須減去r並找到nm * n(m-1)的模塊等等。

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

相關問題