Лабораторная работа 3
Операции над массивами и создание структурированных массивов
Структурированные массивы библиотеки NumPy
Структурированные массивы (structured arrays) и массивы записей (record arrays) обеспечивают эффективное хранилище для сложных неоднородных данных.
Пускай у нас имеется несколько категорий данных (например, имя, возраст и вес) о нескольких людях, и мы хотели бы хранить эти значения для использования в программе на языке Python. Можно сохранить их в отдельных массивах:
name = ['Alice', 'Bob', 'Cathy', 'Doug']
age = [25, 45, 37, 19]
weight = [55.0, 85.5, 68.0, 61.5]
Однако это не очень правильное решение. Ничто не указывает на то, что массивы как-то связаны, лучше было бы использовать для хранения этих данных единую структуру. Библиотека NumPy может это осуществить посредством применения структурированных массивов, представляющих собой массивы с составным типом данных.
Ранее мы создавали простой массив с помощью следующего выражения:
x = np.zeros(4, dtype=int)
Аналогично можно создать структурированный массив, применяя спецификацию сложного типа данных:
# Используем для структурированного массива составной тип данных
data = np.zeros(4, dtype={'names':('name', 'age', 'weight'),
'formats':('U10', 'i4', 'f8')})
print(data.dtype)
[('name', '
'U10' означает «строку в кодировке Unicode максимальной длины 10», 'i4' — «4-байтное (то есть 32-битное) целое число», а 'f8' — «8-байтное (то есть 64-битное) число с плавающей точкой».
Создав пустой массив-контейнер, мы можем заполнить его нашим списком значений:
data['name'] = name
data['age'] = age
data['weight'] = weight
print(data)
[('Alice', 25, 55.0) ('Bob', 45, 85.5) ('Cathy', 37, 68.0)
('Doug', 19, 61.5)]
Как мы и хотели, данные теперь располагаются все вместе в одном удобном блоке памяти.
В структурированных массивах удобно то, что можно ссылаться на значения и по имени, и по индексу:
# Извлечь все имена
data['name']
Out: array(['Alice', 'Bob', 'Cathy', 'Doug'], dtype='# Извлечь первую строку данных
data[0]
Out: ('Alice', 25, 55.0)
# Извлечь имя из последней строки
data[-1]['name']
Out: 'Doug'
Появляется возможность с помощью булева маскирования выполнять и более сложные операции, такие как фильтрация по возрасту:
# Извлечь имена людей с возрастом менее 30
data[data['age'] < 30]['name']
Out: array(['Alice', 'Doug'], dtype='Создание структурированных массивов
Типы данных для структурированных массивов можно задавать несколькими способами. Ранее мы рассмотрели метод с использованием словаря:
np.dtype({'names':('name', 'age', 'weight'),
'formats':('U10', 'i4', 'f8')})
Out: dtype([('name', 'Для ясности можно задавать числовые типы как с применением типов данных языка Python, так и типов dtype библиотеки NumPy:
np.dtype({'names':('name', 'age', 'weight'),
'formats':((np.str_, 10), int, np.float32)})
Out: dtype([('name', 'Составные типы данных можно задавать в виде списка кортежей:
np.dtype([('name', 'S10'), ('age', 'i4'), ('weight', 'f8')])
Out: dtype([('name', 'S10'), ('age', '
Если названия типов для вас не важны, можете задать только сами типы данных в разделенной запятыми строке:
np.dtype('S10,i4,f8')
Out: dtype([('f0', 'S10'), ('f1', '
Сокращенные строковые коды форматов могут показаться запутанными, но они основаны на простых принципах. Первый (необязательный) символ — < или >, означает «число с прямым порядком байтов» или «число с обратным порядком байтов» соответственно и задает порядок значащих битов. Следующий символ задает тип данных: символы, байтовый тип, целые числа, числа с плавающей точкой и т. д. (табл. 1). Последний символ или символы отражают размер объекта в байтах.
Таблица 1. Типы данных библиотеки NumPy
Достарыңызбен бөлісу: |