Python - многомерные массивы - PullRequest
3 голосов
/ 26 ноября 2009

Python не предоставляет встроенную поддержку многомерных массивов. Мне нужно разработать 11-мерный массив и набор функций для работы с ним (в основном, линейная алгебра, векторная арифметика). Однако импорт внешней библиотеки не разрешен . У меня есть код на 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};

Как это можно эффективно реализовать в Python (с хорошей читабельностью )?

PS: максимум для версии Python 2.5.

Ответы [ 7 ]

6 голосов
/ 26 ноября 2009

При таком количестве измерений и невозможности импорта библиотеки я бы пошел (как основной выбор) к словарю, индексируемому кортежами. Таким образом, вы получите очень хороший синтаксис для простой индексации:

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

Вы, вероятно, захотите обернуть его в класс, чтобы добавить функциональность помимо простой индексации, но, не зная, что это , это , что вы хотите за этим (инициализация / значения по умолчанию? Нарезка? Итерация? И т. Д., и т.д ...), просто слишком сложно догадаться. Если вы можете точно указать все, что вы хотите сделать с этим «многомерным массивом», нетрудно показать вам код, который лучше всего его предоставляет!

2 голосов
/ 26 ноября 2009

Я написал Matrix класс здесь:

Многомерный массив в Python

Может использоваться следующим образом:

m = Matrix(4,5,2,6)
m[2,3,1,3] = 'x'
m[2,3,1,3] // -> 'x'
1 голос
/ 01 марта 2016
"""
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 для многомерных массивов.

1 голос
/ 26 ноября 2009

Потенциально очень удобочитаемое решение, хотя, возможно, и с низкой производительностью, будет использовать в качестве ключей элемент с кортежами из 11 элементов:

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

Это также позволяет вам сохранять векторы координат и передавать их как отдельные объекты:

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

Вы можете обеспечить целостность ключа, используя свой собственный класс или подкласс 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.")

Вы можете улучшить производительность, используя собственный класс с тем же интерфейсом __getitem__ / __setitem__, но это даже не нужно делать сначала.

1 голос
/ 26 ноября 2009

Другой возможностью было бы создание одномерного массива, а затем чтение / запись его с использованием функций, которые принимают 11 аргументов индекса. Вы умножаете индексы (основанные на максимуме для каждого измерения), чтобы вычислить позицию в массиве. Сами функции get / set не будут такими уж хорошими (с 11 индексами), но как только вы их напишите, получение и установка индексов массивов будут выглядеть почти так же чисто, как в C. Я не уверен, как будет сравниваться производительность для этого из вложенных списков, но я предполагаю, что это было бы выгодно.

Основная концепция может быть показана в двух измерениях:

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]

И так для больших массивов. Вы можете обобщить это на переменное количество измерений. Вероятно, я бы поместил индексы и измерения в списки, а затем перебрал бы их.

0 голосов
/ 05 августа 2015

Вы можете использовать списки:

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

и так далее.

0 голосов
/ 26 ноября 2009

«Мультиразмерность» - это просто причудливый термин, означающий «много областей памяти». Если вы посмотрите на это в более широком смысле, они просто «одномерны». В любом случае, чтобы предложить альтернативу, вы можете использовать словари.

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

Создайте свои диктовки таким образом, чтобы ваше "11" -ое измерение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...