简体   繁体   English

Python - 多维数组

[英]Python - Multi-Dimensional Arrays

Python does not provide built-in support for multi-dimensional arrays. Python不提供对多维数组的内置支持。 I need to develop an 11-dimensional array and a set of functions to operate on it (mostly linear algebra, vector arithmetics). 我需要开发一个11维数组和一组函数来操作它(主要是线性代数,矢量算术)。 However, no external library import is allowed . 但是, 不允许外部库导入 I have a code in C and trying to port it to Python: 我有一个C代码,并尝试将其移植到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};

How can it be implemented in Python effectively (with good readability )? 如何有效地在Python中实现(具有良好的可读性 )?

PS: For Python 2.5 version at most. PS:最多为Python 2.5版本。

With so many dimensions, and no library imports allowed, I'd go (as the basic choice) for a dictionary indexed by tuples. 有这么多维度,并且不允许库导入,我会(作为基本选择)用于由元组索引的字典。 This way, you get very nice syntax for simple indexing: 这样,您可以获得简单索引的非常好的语法:

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

You'll probably want to wrap it in a class to add functionality beyond simple indexing, but, not knowing what it is that you want beyond that (initialization/defaults? slicing? iteration? etc, etc...), it's just too hard to guess. 您可能希望将它包装在一个类中以添加除简单索引之外的功能,但是,不知道除了那之外你想要的什么(初始化/默认?切片?迭代?等等......),它也是很难猜到。 If you can specify precisely all that you want to do with that "multi-dimensional array", it shouldn't be hard to show you the code that best provides it! 如果你可以准确地指定你想用“多维数组”做的所有事情,那么向你展示最能提供它的代码应该不难!

I've written a Matrix class here: 我在这里写了一个Matrix类:

Multidimensional array in Python Python中的多维数组

It can be used like this: 它可以像这样使用:

m = Matrix(4,5,2,6)
m[2,3,1,3] = 'x'
m[2,3,1,3] // -> 'x'

Another possibility would be to create a 1-dimensional array and then read/write it using functions that take 11 index arguments. 另一种可能性是创建一维数组,然后使用带有11个索引参数的函数读/写它。 You multiply out the indices (based on the max for each dimension) to calculate a position in the array. 您将指数(基于每个维度的最大值)相乘以计算数组中的位置。 The get/set functions themselves won't be all that pretty (with 11 indices) but once you have them written, getting and setting array indices will look almost as clean as it does in C. I'm not sure how performance would compare to that of nested lists but my guess is that it would be favorable. get / set函数本身并不是那么漂亮(有11个索引)但是一旦你编写了它们,获取和设置数组索引看起来就像在C中一样干净。我不确定性能如何比较对于嵌套列表,但我的猜测是有利的。

The basic concept can be shown with 2 dimensions: 基本概念可以用2个维度显示:

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

It gets more complicated with more dimensions, though: 但是,更多尺寸会变得更复杂:

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

And so on for larger arrays. 对于更大的阵列等等。 You could generalize this to a variable number of dimensions. 您可以将其概括为可变数量的维度。 I'd probably put the indices and dimensions into lists and then iterate over them. 我可能会将索引和维度放入列表中,然后迭代它们。

A potentially very legible solution, though probably performance-poor, would use a dict with eleven-element tuples as keys: 一个可能非常清晰的解决方案虽然可能性能不佳,但会使用带有十一元素元组的dict作为键:

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

This also allows you to store the coordinate vectors and pass them around as single objects: 这也允许您存储坐标向量并将它们作为单个对象传递:

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

You could enforce key integrity by either using your own class or a subclass of dict: 您可以通过使用自己的类或dict的子类来强制执行密钥完整性:

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

You could improve performance by using your own class with the same __getitem__ / __setitem__ interface, but that need not even be done at first. 您可以通过使用具有相同__getitem__ / __setitem__接口的自己的类来提高性能,但首先不需要这样做。

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

Prefer numpy.ndarray for multi-dimensional arrays. 首选numpy.ndarray用于多维数组。

"Multi-dimension" is just a fancy term to mean "many memory locations". “多维度”只是一个意思是“许多记忆位置”的术语。 If you look at it in a broader sense, they are just really "1 dimensional". 如果你从更广泛的意义上看它,它们只是真正的“一维”。 Anyway, to suggest an alternative, you can use dictionaries. 无论如何,要建议替代方案,您可以使用词典。

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

Create your dicts this way to your "11"th dimension. 以这种方式创建你的dicts到你的“11”维度。

You could use lists: 你可以使用列表:

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

and so on after that. 等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM