Лучше использовать кортеж или массив Numpy для хранения координат - PullRequest
9 голосов
/ 02 апреля 2010

Я портирую научное приложение C ++ на python, и, поскольку я новичок в python, мне приходят в голову некоторые проблемы:

1) Я определяю класс, который будет содержать координаты (x, y). Эти значения будут доступны несколько раз, но они будут прочитаны только после создания экземпляра класса. Лучше ли использовать кортеж или пустой массив, как в памяти, так и во времени доступа?

2) В некоторых случаях эти координаты будут использоваться для построения комплексного числа, вычисляемого по комплексной функции, и будет использоваться действительная часть этой функции. Предполагая, что не существует способа разделить действительную и сложную части этой функции, а действительную часть нужно будет использовать в конце, может быть, лучше использовать непосредственно сложные числа для хранения (x, y)? Насколько плохи издержки при переходе от сложного к реальному в Python? Код на c ++ выполняет множество таких преобразований, и это сильно тормозит этот код.

3) Также должны быть выполнены некоторые преобразования координат, и для координат будут доступны значения x и y отдельно, преобразование будет выполнено, и результат будет возвращен. Преобразования координат определены в комплексной плоскости, поэтому все же быстрее использовать компоненты x и y напрямую, чем полагаться на комплексные переменные?

Спасибо

Ответы [ 2 ]

6 голосов
/ 02 апреля 2010

С точки зрения потребления памяти, массивы numpy более компактны, чем кортежи Python. В массиве numpy используется один непрерывный блок памяти. Все элементы массива numpy должны быть объявленного типа (например, 32-разрядный или 64-разрядный с плавающей запятой.) Кортеж Python не обязательно использует непрерывный блок памяти, а элементы кортежа могут быть произвольными объектами Python, которые обычно потребляет больше памяти, чем числовые типы.

Таким образом, эта проблема является победой для numpy (при условии, что элементы массива могут быть сохранены как числовой тип numpy).

Что касается скорости, я думаю, что выбор сводится к вопросу: «Можете ли вы векторизовать свой код?»

То есть вы можете выразить свои вычисления как операции, выполненные над целыми массивами поэлементно.

Если код может быть векторизован, то numpy, скорее всего, будет быстрее, чем кортежи Python. (Единственный случай, который я мог бы себе представить, где это может быть не так, это если бы у вас было много очень маленьких кортежей. В этом случае накладные расходы на формирование массивов numpy и единовременные затраты на импорт numpy могли бы заглушить выгоду векторизации.)

Примером кода, который нельзя было бы векторизовать, было бы, если бы ваш расчет включал просмотр, скажем, первого комплексного числа в массиве z, выполнение вычисления, которое дает целочисленный индекс idx, а затем извлечение z[idx], выполняя вычисление для этого числа, которое производит следующий индекс idx2, затем извлекает z[idx2] и т. д. Этот тип вычисления может быть не векторизованным. В этом случае вы также можете использовать кортежи Python, поскольку вы не сможете использовать силу numpy.

Я бы не беспокоился о скорости доступа к действительным / воображаемым частям комплексного числа. Я предполагаю, что проблема векторизации, скорее всего, определит, какой метод быстрее. (Хотя, между прочим, numpy может преобразовать массив комплексных чисел в их действительные части, просто перешагнув через сложный массив, пропуская все остальные числа и просматривая результат как числа с плавающей точкой. Более того, синтаксис очень прост: если z - это сложный массив NumPy, тогда z.real - это реальные части в виде массива с плавающей точкой. Это должно быть намного быстрее, чем чистый подход Python, использующий понимание списка для поиска атрибутов: [z.real for z in zlist].)

Просто из любопытства, какова ваша причина переноса кода C ++ на Python?

3 голосов
/ 02 апреля 2010
Массив

A numpy с дополнительным измерением более компактен при использовании памяти и, по крайней мере, так же быстро !, как массив numpy кортежей; комплексные числа, по крайней мере, так же хороши или даже лучше, в том числе для вашего третьего вопроса. Кстати, вы, возможно, заметили, что - в то время как вопросы, задаваемые позже, чем ваши, получали множество ответов, - вы закладывали ложь: отчасти причина, без сомнения, в том, что если задать три вопроса в вопросе, респонденты отключаются. Почему бы просто не задать один вопрос на вопрос? Это не так, как если бы вы платили за вопросы или что-то еще, вы знаете ...! -)

...