2015-07-10 2 views
1

Я пытаюсь построить structured array в Python, к которому можно получить доступ по именам столбцов и строк. Возможно ли это с помощью метода numpy structured array?Двухмерный структурированный массив

Пример: Мой массив должен иметь примерно такую ​​форму:

My_array =  A B C 
       E 1 2 3 
       F 4 5 6 
       G 7 8 9 

И я хочу, чтобы иметь возможность сделать следующее:

My_array["A"]["E"] = 1 
My_array["C"]["F"] = 6 

Можно ли это сделать в pyhton используя structured arrays или есть другой тип структуры, который более подходит для такой задачи?

+1

Вы можете использовать [pandas] (http: //pandas.pydata.org) – yangjie

+0

@yangjie танки, 'pandas' выглядят обещаниями. Тем не менее, я должен передавать эти данные через интерфейсы MPI. «Numpy» будет хорошим решением, поскольку они быстрее и проще проходят через интерфейсы. – swot

ответ

1

С повторением вы можете получить доступ к столбцам с точечной нотацией или с конкретной ссылкой на имя столбца. Для строк они доступны по номеру строки. Я не видел, как они обращались с помощью имени строки, например:

>>> import numpy as np 
>>> a = np.arange(1,10,1).reshape(3,3) 
>>> dt = np.dtype([('A','int'),('B','int'),('C','int')]) 
>>> a.dtype = dt 
>>> r = a.view(type=np.recarray) 
>>> r 
rec.array([[(1, 2, 3)], 
     [(4, 5, 6)], 
     [(7, 8, 9)]], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 
>>> r.A 
array([[1], 
     [4], 
     [7]]) 
>>> r['A'] 
array([[1], 
     [4], 
     [7]]) 
>>> r.A[0] 
array([1]) 
>>> a['A'][0] 
array([1]) 
>>> # now for the row 
>>> >>> r[0] 
rec.array([(1, 2, 3)], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 
>>> 

Вы можете указать DTYPE и тип в то же время

>>> a = np.ones((3,3)) 
>>> b = a.view(dtype= [('A','<f8'), ('B','<f8'),('C', '<f8')], type = np.recarray) 
>>> b 
rec.array([[(1.0, 1.0, 1.0)], 
     [(1.0, 1.0, 1.0)], 
     [(1.0, 1.0, 1.0)]], 
     dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<f8')]) 
>>> b.A 
array([[ 1.], 
     [ 1.], 
     [ 1.]]) 
>>> b.A[0] 
array([ 1.]) 
+0

Спасибо за предложение. Я думаю, что я могу обойти индексацию столбцов. Однако, если я использую 'np.zeros ((3,3))' вместо arange и reshape, я получаю массив, который имеет две тройки в строке: '[(0.0, 0.0, 0.0), (0.0, 0.0, 0.0)] '. Но я просто хочу одну тройку. – swot

+0

'dtype = [('A', np.float), ('B', np.float), ('C', np.float)]' решает проблему. Может ли кто-нибудь сказать мне, почему? – swot

+1

swot Я добавляю строку к своему оригинальному сообщению –

1

Базовый структурированный массив дает вам то, что может индексироваться одним именем:

In [276]: dt=np.dtype([('A',int),('B',int),('C',int)]) 
In [277]: x=np.arange(9).reshape(3,3).view(dtype=dt) 
In [278]: x 
Out[278]: 
array([[(0, 1, 2)], 
     [(3, 4, 5)], 
     [(6, 7, 8)]], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 

In [279]: x['B'] # index by field name 
Out[279]: 
array([[1], 
     [4], 
     [7]]) 

In [280]: x[1] # index by row (array element) 
Out[280]: 
array([(3, 4, 5)], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 

In [281]: x['B'][1] 
Out[281]: array([4]) 

In [282]: x.shape # could be reshaped to (3,) 
Out[282]: (3, 1) 

Подход к представлению создал массив 2d, но только с одним столбцом. Обычные столбцы заменяются полями dtype. Это 2d, но с завихрением. Используя view, буфер данных не изменяется; dtype просто предоставляет другой способ доступа к этим «столбцам». dtype Поля, технически, не являются измерениями. Они не регистрируются в массиве .shape или .ndim. Также вы не можете использовать x[0,'A'].

recarray делает то же самое, но добавляет возможность доступа к полям в качестве атрибутов, например. x.B - это то же самое, что и у x['B'].

rows по-прежнему необходимо получить номер индекса.

Другой способ построения структурированного массива - это определенные значения в виде списка кортежей.

In [283]: x1 = np.arange(9).reshape(3,3) 
In [284]: x2=np.array([tuple(i) for i in x1],dtype=dt) 
In [285]: x2 
Out[285]: 
array([(0, 1, 2), (3, 4, 5), (6, 7, 8)], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 
In [286]: x2.shape 
Out[286]: (3,) 

ones, zeros, empty также построить основные структурированные массивы

In [287]: np.ones((3,),dtype=dt) 
Out[287]: 
array([(1, 1, 1), (1, 1, 1), (1, 1, 1)], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 

Я могу построить массив, который индексируется с 2-мя именами полей, по гнездящихся dtypes:

In [294]: dt1=np.dtype([('D',int),('E',int),('F',int)]) 

In [295]: dt2=np.dtype([('A',dt1),('B',dt1),('C',dt1)]) 

In [296]: y=np.ones((),dtype=dt2) 

In [297]: y 
Out[297]: 
array(((1, 1, 1), (1, 1, 1), (1, 1, 1)), 
     dtype=[('A', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')]), ('B', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')]), ('C', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')])]) 

In [298]: y['A']['F'] 
Out[298]: array(1) 

Но откровенно это довольно запутанно. Я даже не понял, как установить элементы в arange(9) (без повторения имен полей).

Структурированные массивы чаще всего производятся путем чтения csv файлов с np.genfromtxt (или loadtxt). Результатом является именованное поле для каждого помеченного столбца и пронумерованная «строка» для каждой строки в файле.

+0

не могу отформатировать это правильно в комментарии, так что несите меня. Продолжить с вашей строки 298 ... В [299]: z = y.view (type = np.recarray), тогда In [300]: zA ['F'] или In [3XX]: zAF дает массив (1) recarrays просто добавляют возможность просто arry ['field'] с обозначением arry.field, так что zAF 'выглядит' лучше, чем эквивалент среза. –

+0

Да, мой dtype 'dt2' можно отличить как' recarray' и получить доступ с помощью 'xAF '. Чем сложнее dtype, тем лучше выглядит 'recarray'. – hpaulj

+0

@hpaulj Спасибо за обсуждение разных возможностей. Я не знал о возможности гнезда 'dtypes'. Возможно, я проведу последнее предложение с вложенными 'dtypes' позже. – swot

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