2013-03-03 1 views
0

У меня есть набор данных, которые я бы хотел обработать numpy. Данные можно рассматривать как набор точек в пространстве с дополнительной переменной свойства, которую я хотел бы обрабатывать как объект. В зависимости от набора данных векторы могут быть длиной 1, 2 или 3, но одинаковой длины для всех точек в заданном наборе данных. Объект свойства - это настраиваемый класс, который может быть одинаковым для любых двух заданных точек.Массив Numpy как вектор с уникальным свойством

Так что рассмотрите эти данные как случайный пример (C и H представляют собой объекты, которые содержат атомные свойства для углерода или водорода ... или просто какой-то случайный объект). Они не будут считываться через файл, а создаваться с помощью алгоритма. Здесь объект C может быть одинаковым или может быть другим (например, изотопом).

Example 3D data set (just abstract representation) 
C 1 2 3 
C 3 4 5 
H 1 1 4 

Я хотел бы иметь Numpy массив, содержащий все атомные позиции, так что я могу выполнять NumPy операции, такие как вектор манипуляции и такие, как функция перевода def translate(data,vec):return data + vec. Я также хотел бы обрабатывать объекты свойств параллельно. Один из вариантов состоял бы в том, чтобы иметь два отдельных массива для обоих, но если я удалю элемент из одного, я должен будет явно удалить значение массива свойств. С этим можно было бы справиться.

Я рассматривал numpy.recarray

x = np.array([(1.0,2,3, "C"), (3.0,2,3, "H")], dtype=[('x', "float64"),('y',"float6 

4 "), ('г'," float64"), ('тип', объект)])

Но кажется shape этого массива является (2,), что означает, что каждая запись обрабатывается независимо Кроме того, я не могу понять, как получить вектор манипуляции работать с этим типом:.

def translate(data,vec):return data + vec 
translate(x,np.array([1,2,3])) 
... 
TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'numpy.ndarray' 

Is numpy.recarray что я должен использовать? Есть ли лучший способ справиться с этим более простым способом, так что у меня есть отдельная численная матрица точек с параллельным массивом object, которые связаны в случае удаления элемента (np.delete)? Я также кратко рассмотрел возможность записи объекта массива, который расширяет ndarray, но я чувствую, что это может быть ненужным и потенциально катастрофическим.

Любые мысли или предложения были бы очень полезными.

ответ

2

поле recarray может быть ndarray, если передать кортеж (name, type, shape) как DTYPE поля:

In [9]: 

import numpy as np 

x = np.array([((1.0,2,3), "C"), ((3.0,2,3), "H")], dtype=[('xyz', "float64", (3,)), ('type', object)]) 

In [11]: 

np.delete(x, 0) 

Out[11]: 

array([([3.0, 2.0, 3.0], 'H')], 
     dtype=[('xyz', '<f8', (3,)), ('type', 'O')]) 

In [12]: 

x["xyz"] 

Out[12]: 

array([[ 1., 2., 3.], 
     [ 3., 2., 3.]]) 

In [14]: 

x["xyz"] + (10, 20, 30) 

Out[14]: 

array([[ 11., 22., 33.], 
     [ 13., 22., 33.]]) 

Для вашего перевода функции:

def translate(data,vec): 
    tmp = data.copy() 
    tmp["xyz"] += vect 
    return tmp 

Если вы хотите более гибкие функции, вы можете рассмотреть возможность использования Pandas.DataFrame.

+0

Спасибо! Это именно то, что я искал. Он поскользнулся, и я понял, что вы можете изменить размеры одной из структур. – scicalculator

1

Если вы имеете дело с коллекциями атомов, вы можете использовать Atoms class от Atomic Simulation Environment (ASE). Он хранит типы атомов, позиции и имеет похожие методы, чтобы манипулировать ими.

+0

Спасибо за эту ссылку, я не знал об этом. Я на самом деле собираю кристаллографию и молекулярную визуализацию/анализ/MD suite. Этот пакет выглядит довольно мощным и будет хорошим пакетом, чтобы увидеть, что другие делают в той же области. Возможно, также возможно сотрудничество для работы с ним, я полагаю. – scicalculator

+0

Было бы неплохо осмотреть то, что уже есть, и, возможно, расширить что-то с большой пользовательской базой. Это увеличило бы шансы, что проект не закончится как «еще одна незавершенная попытка» создать молекулярный инструмент визуализации/анализа ... :-) –

0

Один быстрый и грязный путь был бы установить последний (или вообще любой) столбец числовая поиска в словаре этикетками:

>>> import numpy 
>>> labels = ['H', 'C', 'O'] 
>>> labels_refs = dict(zip(labels, numpy.arange(len(labels), dtype='float64'))) 
>>> reverse_labels_refs = dict(zip(numpy.arange(len(labels), dtype='float64'), labels)) 
>>> x = numpy.array([ 
...  [1.0,2,3, labels_refs['C']], 
...  [3.0,2,3, labels_refs['H']], 
...  [2.0,2,3, labels_refs['C']]]) 
>>> x 
array([[ 1., 2., 3., 1.], 
     [ 3., 2., 3., 0.], 
     [ 2., 2., 3., 1.]]) 
>>> extract_refs = numpy.vectorize(
...   lambda label_ref: reverse_labels_refs[label_ref]) 
>>> labels = extract_refs(x[:, -1]) # Turn the last column back into labels 
>>> labels 
array(['C', 'H', 'C'], 
     dtype='|S8') 

Вы также можете поиска строк по их меткам (в качестве примера):

>>> x[numpy.where(x[:,-1] == labels_refs['C']), :-1] 
array([[[ 1., 2., 3.], 
     [ 2., 2., 3.]]]) 
+0

Спасибо. Это, безусловно, можно использовать, но для этого требуется предварительное знание всего набора возможных ссылок. Было бы лучше иметь очень жидкую схему для моих целей. – scicalculator