2009-11-26 61 views
3

Python不提供對多維數組的內置支持。我需要開發一個11維數組和一組函數來對它進行操作(主要是線性代數,向量運算)。但是,不允許外部庫導入。我有一個在C代碼,並試圖將它移植到Python:Python - 多維數組

typedef vec3_t float[3]; 
vec3_t Array[dim0][dim1][dim2][dim3][dim4][dim5][dim6][dim7][dim8][dim9][dim10]; 
Array[0][0][0][0][0][0][0][0][0][0][1] = {1.0, 0.0, 0.0}; 

如何可以把它用Python實現有效(有良好的可讀性)?

PS:最多支持Python 2.5版本。

回答

6

有這麼多尺寸,並允許無庫進口,我想去(作爲基本選擇)爲由元組索引的字典。這樣一來,你會得到簡單的索引非常好的語法:

Array = dict() 
Array[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] = [1.0, 0.0, 0.0] 

你可能想將其包裝在一個類中添加功能超出了簡單的索引,但是,不知道什麼是要超越(初始化/默認?切片?迭代?等,等等),這太難以猜測了。如果您可以精確指定您想要對「多維數組」進行的所有操作,則不應該很難向您展示最佳的代碼!

+0

我需要稍後不同的矩陣乘法,向量運算 – psihodelia 2009-11-26 06:39:39

+3

@psihodelia:在這種情況下,您的選項僅限於使用numpy(外部庫),在因特網上查找庫或自行編寫代碼。 – 2009-11-26 06:46:05

+2

我不確定一個「後來不同」的矩陣乘法與正常矩陣乘法有何區別(甚至不知道在11維陣列上如何定義矩陣乘法,老實說!),也不知道你需要什麼「矢量算術」在11維陣列上執行。如果你可以用C編寫代碼(或者僞代碼),那麼你可以用Python編寫代碼,當然也可以更簡潔一些...... - 但是,它仍然是**很多編碼,只是爲了避免導入任何現有的模塊。爲什麼你不能導入像pyarray這樣的純python庫並保存自己的一些工作?) – 2009-11-26 06:49:04

0

「多維度」僅僅是一個很好的術語,意思是「許多存儲位置」。如果你從更廣泛的角度來看它,它們就是真正的「一維」。無論如何,建議一個替代方案,你可以使用字典。

>>> d={} 
>>> d[0]={} 
>>> d[0][0]="1" 
>>> d[0] 
{0: '1'} 

通過這種方式創建您的字典到您的「第11」維。

1

另一種可能性是創建一個1維數組,然後使用帶有11個索引參數的函數讀/寫它。您將索引乘以(根據每個維度的最大值)以計算數組中的位置。 get/set函數本身不會很漂亮(有11個索引),但是一旦你寫了它們,獲取和設置數組索引就會像C中一樣乾淨。我不確定性能如何與之比較到嵌套列表,但我的猜測是,這將是有利的。

的基本概念可被示出爲具有2個維度:

def readArray2(arr,i1,i2,dim2): 
    index = i1 * dim2 + i2 
    return arr[index] 

它得到具有更多維度更復雜,但:

def readArray3(arr,i1,i2,i3,dim2,dim3): 
    index = i1 * dim2 * dim3 + i2 * dim3 + i3 
    return arr[index] 

等了更大的陣列。您可以將其推廣到可變數量的維度。我可能會將索引和維度放入列表中,然後遍歷它們。

1

一個潛在的非常清晰的解決方案,雖然可能業績不佳,將使用十一個元素的元組的字典作爲鍵:

>>> d[0,1,2,3,4,5,6,7,8,9,0] = [1.0, 0.0, 0.0] 

這也允許你存儲的座標矢量和周圍將它們作爲單一對象:

>>> class Space(dict): 
>>>  def __setitem__(self, key, value): 
>>>   if len(key) == 11: 
>>>    dict.__setitem__(self, key, value) 
>>>   else: 
>>>    raise IndexError("Keys must be eleven-dimensional vectors.") 

>>> coord = (0,1,2,3,4,5,6,7,8,9,0) 
>>> d[coord] 
[1.0, 0.0, 0.0] 

您可以通過或者使用你自己的類或字典的一個子類強制密鑰完整性3210

您可以通過使用您自己的類與相同的接口來提高性能,但是這不需要一開始就完成。

0

你可以用列表:

list = [ [ [ '' for i in range(dim0) ] for j in range(dim1) ] for k in range(dim2) ] 

等以後上。

1
""" 
Create multi-dimensional array for given dimensions - (x1, x2, x3, ..., xn) 

@author: Naimish Agarwal 
""" 


def multi_dimensional_array(value, *dim): 
    """ 
    Create multi-dimensional array 
    :param dim: a tuple of dimensions - (x1, x2, x3, ..., xn) 
    :param value: value with which multi-dimensional array is to be filled 
    :return: multi-dimensional array 
    """ 

    if len(dim) > 1: 
     return [multi_dimensional_array(value, *dim[1:]) for _ in xrange(dim[0])] 
    else: 
     return [value for _ in xrange(dim[0])] 


if __name__ == "__main__": 
    multi_array = multi_dimensional_array(False, *(2, 3, 1)) 
    print multi_array 

優選numpy.ndarray用於多維數組。