2009-11-26 62 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用于多维数组。