В предыдущих примерах вы видели только одно- или двухмерные массивы. Но NumPy позволяет создавать массивы, которые будут более сложными не только в плане размера, но и по своей структуре. Они называются структурированными массивами. В них вместо отдельных элементов содержатся structs
или записи.
Например, можно создать простой массив, состоящий из structs
в качестве элементов. Благодаря параметру dtype
можно определить условия, которые будут представлять элементы struct
, а также тип данных и порядок.
byte | b1 |
int | i1, i2, i4, i8 |
float | f2, f4, f8 |
complex | c8, c16 |
string | a<n> |
Например, если необходимо определить struct
, содержащий целое число, строку длиной 6 символов и булево значение, потребуется обозначить три типа данных в dtype
в нужном порядке.
Примечание: результат
dtype
и другие атрибуты формата могут отличаться на разных операционных системах и дистрибутивах Python.
>>> structured = np.array([(1, 'First', 0.5, 1+2j),(2, 'Second', 1.3, 2-2j), (3, 'Third', 0.8, 1+3j)], dtype=('i2, a6, f4, c8'))
>>> structured
array([(1, b'First', 0.5, 1+2.j),
(2, b'Second', 1.3, 2.-2.j),
(3, b'Third', 0.8, 1.+3.j)],
dtype=[('f0', '<i2'), ('f1', 'S6'), ('f2', '<f4'), ('f3', '<c8')])
Тип данных можно указать и явно с помощью int8, uint8, float16, complex16
и так далее.
>>> structured = np.array([(1, 'First', 0.5, 1+2j),(2, 'Second', 1.3,2-2j), (3, 'Third', 0.8, 1+3j)],dtype=('int16, a6, float32, complex64'))
>>> structured
array([(1, b'First', 0.5, 1.+2.j),
(2, b'Second', 1.3, 2.-2.j),
(3, b'Third', 0.8, 1.+3.j)],
dtype=[('f0', '<i2'), ('f1', 'S6'), ('f2', '<f4'), ('f3', '<c8')])
В обоих случаях будет одинаковый результат. В массиве имеется последовательность dtype
, содержащая название каждого элемента struct
с соответствующим типом данных.
Указывая соответствующий индекс, вы получаете нужную строку, включающую struct
.
>>> structured[1]
(2, 'bSecond', 1.3, 2.-2.j)
Имена, присваиваемые каждому элементу struct
автоматически, по сути, представляют собой имена колонок массива. Используя их как структурированный указатель, можно ссылаться на все элементы одного типа или одной и той же колонки.
>>> structured['f1']
array([b'First', b'Second', b'Third'],
dtype='|S6')
Имена присваиваются автоматически с символом f
(он значит field (поле)) и увеличивающимся целым числом, обозначающим позицию в последовательности. Но было бы куда удобнее иметь более логичные имена. Это можно сделать в момент создания массива:
>>> structured = np.array([(1,'First',0.5,1+2j),
(2,'Second',1.3,2-2j), (3,'Third',0.8,1+3j)],
dtype=[('id','i2'),('position','a6'),('value','f4'),('complex','c8')])
>>> structured
array([(1, b'First', 0.5, 1.+2.j),
(2, b'Second', 1.3, 2.-2.j),
(3, b'Third', 0.8, 1.+3.j)],
dtype=[('id', '<i2'), ('position', 'S6'), ('value', '<f4'), ('complex', '<c8')])
Или позже, переопределив кортежи имен, присвоенных атрибуту dtype
структурированного массива:
>>> structured.dtype.names = ('id','order','value','complex')
Теперь можно использовать понятные имена для разных типов полей:
>>> structured['order']
array([b'First', b'Second', b'Third'], dtype='|S6')