2012-03-20 3 views
6

Предположим, у меня есть класс под названием Star, который имеет атрибут color. Я могу получить цвет с star.color.Получение атрибутов из массивов объектов в NumPy

Но что, если у меня есть массив NumPy этих объектов Star. Каков предпочтительный способ получения массива цветов?

я могу сделать это с

colors = np.array([s.color for s in stars]) 

Но это лучший способ сделать это? Было бы здорово, если бы я мог просто сделать colors = star.color или colors = star->color и т. Д., Как на некоторых других языках. Есть ли простой способ сделать это в numpy?

+0

Возможный дубликат [numpy array of objects] (http://stackoverflow.com/questions/4877624/numpy-array-of-objects) – YXD

ответ

7

Самое близкое к тому, что вы хотите использовать recarray вместо ndarray объектов Python:

num_stars = 10 
dtype = numpy.dtype([('x', float), ('y', float), ('colour', float)]) 
a = numpy.recarray(num_stars, dtype=dtype) 
a.colour = numpy.arange(num_stars) 
print a.colour 

печатает

[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] 

Использование массива NumPy в Python объекты, как правило, является менее эффективным чем использование простой list, а recarray хранит данные в более эффективном формате.

+0

Прохладный. Поэтому он делает их такими же, как массивы IDL структур, которые я хотел. Как это использовать, если у меня уже есть обычный класс python? Есть ли простой способ сделать это? – Dave31415

+0

@ Dave31415: IDL? Итак, вы астроном, или кто-либо * вне * астрономии действительно использует это? Что касается вашего вопроса: не видя определения класса, это немного сложно ответить. Используя NumPy, вы, как правило, не хотите, чтобы «методы» работали на отдельных записях, а скорее на функциях, которые могут работать сразу со всем массивом. Таким образом, вам нужно будет векторизовать свои методы. –

+0

Попытка быть бывшим астрономом. Поэтому я предполагаю, что вы говорите, что массивы объектов не являются предпочтительной структурой данных для numpy. Но что тогда? Я могу создавать классы, чьи атрибуты являются массивами numpy. Это лучший способ? Это не похоже на то, что я хочу. – Dave31415

3

Вы можете использовать numpy.fromiter(s.color for s in stars) (обратите внимание на отсутствие квадратных скобок). Это позволит избежать создания промежуточного списка, который, я думаю, вам может быть интересно, если вы используете numpy.

(Спасибо @SvenMarnach и @DSM за их исправления ниже).

+2

К сожалению, это не сработает: вы получите что-то вроде 'array (<объект-генератор at 0x9cff34c>, dtype = object)'. (У меня когда-то была ошибка в моем коде, которая была в конечном итоге из-за того, что я думал, что это сработает.) – DSM

+1

Для этого вам нужно использовать 'numpy.fromiter()'. –

+2

Примечание: чтобы заставить это работать в последних numpys, вам нужно 'numpy.fromiter ((s.color для s в звездах), float)'.Кроме того, добавление 'count = len (stars)' сделает его более эффективным для длинных массивов. – Dougal

Смежные вопросы