Создание массивов
См. также
Введение
Существует 6 основных механизмов для создания массивов:
- Преобразование из других структур Python (например, списков и кортежей)
- Встроенные функции NumPy для создания массивов (например, arange, ones, zeros и т.д.)
- Копирование, объединение или изменение существующих массивов
- Чтение массивов из диска, как из стандартных, так и из пользовательских форматов
- Создание массивов из сырых байтов с помощью строк или буферов
- Использование специальных функций библиотеки (например, random)
Эти методы можно использовать для создания ndarrays или структурированных массивов. В этом документе будут рассмотрены общие методы создания ndarrays.
1) Преобразование Python-последовательностей в массивы NumPy
Массивы NumPy можно определить, используя Python-последовательности, такие как списки и кортежи. Списки и кортежи определяются с помощью [...] и (...), соответственно. Списки и кортежи могут определять создание ndarrays:
- список чисел создаст одномерный массив,
- список списков создаст двумерный массив,
- дальнейшие вложенные списки создадут массивы более высоких размерностей. В целом, любой массивный объект называется ndarray в NumPy.
>>> a1D = np.array([1, 2, 3, 4]) >>> a2D = np.array([[1, 2], [3, 4]]) >>> a3D = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
При использовании numpy.array для определения нового массива, необходимо учитывать тип данных элементов в массиве, который может быть явно указан. Эта функция обеспечивает больший контроль над базовыми структурами данных и тем, как элементы обрабатываются в функциях C/C++. Когда значения не помещаются, и вы используете dtype, NumPy может выдать ошибку:
>>> np.array([127, 128, 129], dtype=np.int8) Traceback (most recent call last): ... OverflowError: Python integer 128 out of bounds for int8
8-битовое знаковое целое число представляет целые числа от -128 до 127. Присваивание int8 массиву целых чисел, выходящих за этот диапазон, приводит к переполнению. Этот аспект часто может быть неверно понят. Если вы выполняете вычисления с несовпадающими dtypes, вы можете получить нежелательные результаты, например:
>>> a = np.array([2, 3, 4], dtype=np.uint32)
>>> b = np.array([5, 6, 7], dtype=np.uint32)
>>> c_unsigned32 = a - b
>>> print('unsigned c:', c_unsigned32, c_unsigned32.dtype)
unsigned c: [4294967293 4294967293 4294967293] uint32
>>> c_signed32 = a - b.astype(np.int32)
>>> print('signed c:', c_signed32, c_signed32.dtype)
signed c: [-3 -3 -3] int64
Обратите внимание, что при выполнении операций с двумя массивами одного dtype: uint32, результирующий массив имеет тот же тип. При выполнении операций с различными dtype, NumPy назначит новый тип, который удовлетворяет всем элементам массива, участвующим в вычислении, здесь uint32 и int32 могут быть представлены в виде int64.
По умолчанию NumPy создает массивы либо в 32- или 64-битных знакомых целых числах (зависит от платформы и соответствует размеру C long ) или числах двойной точности с плавающей запятой. Если ожидается, что ваши целочисленные массивы будут иметь определенный тип, то необходимо указать dtype при создании массива.
2) Встроенные функции NumPy для создания массивов
NumPy имеет более 40 встроенных функций для создания массивов, как описано в Процедурах создания массивов. Эти функции можно разделить примерно на три категории, исходя из размерности создаваемого массива:
- Одномерные массивы
- Двумерные массивы
- ndarrays
1 - Функции создания одномерных массивов
Функции создания одномерных массивов, например, numpy.linspace и numpy.arange, обычно требуют как минимум двух входных данных, start и stop.
numpy.arange создает массивы с регулярно увеличивающимися значениями. Для получения полной информации и примеров см. документацию. Ниже приведены несколько примеров:
>>> np.arange(10) array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> np.arange(2, 10, dtype=float) array([2., 3., 4., 5., 6., 7., 8., 9.]) >>> np.arange(2, 3, 0.1) array([2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9])
Примечание: лучшей практикой для numpy.arange является использование целочисленных начальных, конечных и шаговых значений. Существуют некоторые тонкости, связанные с dtype. Во втором примере dtype определен. В третьем примере массив dtype=float для размещения шага 0.1. Из-за ошибки округления значение stop иногда включается.
numpy.linspace создаст массивы с заданным количеством элементов, равномерно распределенных между заданными начальными и конечными значениями. Например:
>>> np.linspace(1., 4., 6) array([1. , 1.6, 2.2, 2.8, 3.4, 4. ])
Преимущество этой функции создания состоит в том, что вы гарантируете количество элементов и начальную и конечную точки. Предыдущий arange(start, stop, step) не будет включать значение stop.
2 - Функции создания двумерных массивов
Функции создания двумерных массивов, например, numpy.eye, numpy.diag и numpy.vander, определяют свойства специальных матриц, представленных как двумерные массивы.
np.eye(n, m) определяет двумерную единичную матрицу. Элементы, где i=j (индекс строки и индекс столбца равны), равны 1, а остальные - 0, как показано ниже:
>>> np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
>>> np.eye(3, 5)
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.]])
numpy.diag может определить либо квадратный двумерный массив с заданными значениями по диагонали, либо, если задан двумерный массив, возвращает одномерный массив, содержащий только диагональные элементы. Эти две функции создания массивов могут быть полезны при выполнении линейной алгебры, как показано ниже:
>>> np.diag([1, 2, 3])
array([[1, 0, 0],
[0, 2, 0],
[0, 0, 3]])
>>> np.diag([1, 2, 3], 1)
array([[0, 1, 0, 0],
[0, 0, 2, 0],
[0, 0, 0, 3],
[0, 0, 0, 0]])
>>> a = np.array([[1, 2], [3, 4]])
>>> np.diag(a)
array([1, 4])
vander(x, n) определяет матрицу Вандермонда в качестве двумерного массива NumPy. Каждый столбец матрицы Вандермонда представляет собой убывающую степень входного одномерного массива или списка или кортежа, x где наивысший порядок полинома равен n-1. Эта процедура создания массива полезна для генерации моделей линейных наименьших квадратов, как показано ниже:
>>> np.vander(np.linspace(0, 2, 5), 2)
array([[0. , 1. ],
[0.5, 1. ],
[1. , 1. ],
[1.5, 1. ],
[2. , 1. ]])
>>> np.vander([1, 2, 3, 4], 2)
array([[1, 1],
[2, 1],
[3, 1],
[4, 1]])
>>> np.vander((1, 2, 3, 4), 4)
array([[ 1, 1, 1, 1],
[ 8, 4, 2, 1],
[27, 9, 3, 1],
[64, 16, 4, 1]])
3 - Общие функции создания ndarray
Функции создания ndarray, например, numpy.ones, numpy.zeros и random, определяют массивы на основе желаемой формы. Функции создания ndarray могут создавать массивы любой размерности, указав количество размерностей и длину вдоль этой размерности в кортеже или списке.
numpy.zeros создаст массив, заполненный значениями 0 с указанной формой. По умолчанию тип данных - float64:
>>> np.zeros((2, 3))
array([[0., 0., 0.],
[0., 0., 0.]])
>>> np.zeros((2, 3, 2))
array([[[0., 0.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[0., 0.]]])
numpy.ones создаст массив, заполненный значениями 1. Она идентична zeros по всем другим параметрам, как показано ниже:
>>> np.ones((2, 3))
array([[1., 1., 1.],
[1., 1., 1.]])
>>> np.ones((2, 3, 2))
array([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])
Метод random результата default_rng создаст массив, заполненный случайными значениями от 0 до 1. Он включен в библиотеку numpy.random. Ниже созданы два массива с формами (2,3) и (2,3,2) соответственно. Зерно установлено в 42, чтобы вы могли воспроизвести эти псевдослучайные числа:
>>> from numpy.random import default_rng
>>> default_rng(42).random((2,3))
array([[0.77395605, 0.43887844, 0.85859792],
[0.69736803, 0.09417735, 0.97562235]])
>>> default_rng(42).random((2,3,2))
array([[[0.77395605, 0.43887844],
[0.85859792, 0.69736803],
[0.09417735, 0.97562235]],
[[0.7611397 , 0.78606431],
[0.12811363, 0.45038594],
[0.37079802, 0.92676499]]])
numpy.indices создаст набор массивов (упакованных как массив с одной более высокой размерностью), по одному на размерность, при этом каждый представляет собой вариацию по этой размерности:
>>> np.indices((3,3))
array([[[0, 0, 0],
[1, 1, 1],
[2, 2, 2]],
[[0, 1, 2],
[0, 1, 2],
[0, 1, 2]]])
Это особенно полезно для оценки функций многих размерностей на регулярной сетке.
3) Копирование, объединение или изменение существующих массивов
После создания массивов вы можете копировать, объединять или изменять эти существующие массивы для создания новых массивов. Когда вы присваиваете массив или его элементы новой переменной, вы должны явно numpy.copy массив, в противном случае переменная является представлением исходного массива. Рассмотрим следующий пример:
>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> b = a[:2]
>>> b += 1
>>> print('a =', a, '; b =', b)
a = [2 3 3 4 5 6] ; b = [2 3]
В этом примере вы не создали новый массив. Вы создали переменную, b которая отображает первые 2 элемента a. Когда вы добавили 1 к b, вы получите тот же результат, добавив 1 к a[:2]. Если вы хотите создать новый массив, используйте функцию создания массива numpy.copy следующим образом:
>>> a = np.array([1, 2, 3, 4])
>>> b = a[:2].copy()
>>> b += 1
>>> print('a = ', a, 'b = ', b)
a = [1 2 3 4] b = [2 3]
Дополнительную информацию и примеры см. в разделе Копии и представления.
Существует ряд функций для объединения существующих массивов, например, numpy.vstack, numpy.hstack и numpy.block. Вот пример объединения четырех 2x2 массивов в 4x4 массив с помощью block:
>>> A = np.ones((2, 2))
>>> B = np.eye(2, 2)
>>> C = np.zeros((2, 2))
>>> D = np.diag((-3, -4))
>>> np.block([[A, B], [C, D]])
array([[ 1., 1., 1., 0.],
[ 1., 1., 0., 1.],
[ 0., 0., -3., 0.],
[ 0., 0., 0., -4.]])
Другие функции используют аналогичный синтаксис для объединения массивов nd. Обратитесь к документации функции для получения дополнительных примеров и синтаксиса.
4) Чтение массивов из файла, как стандартных, так и пользовательских форматов
Это наиболее распространенный случай создания больших массивов. Подробности сильно зависят от формата данных в файле. В этом разделе приведены общие рекомендации по обработке различных форматов. Более подробные примеры ввода-вывода см. в разделе Как читать и записывать файлы.
Стандартные двоичные форматы
В различных областях используются стандартные форматы данных массивов. Ниже приведены форматы с известными библиотеками Python для их чтения и возврата массивов NumPy (могут быть и другие, для которых возможно чтение и преобразование в массивы NumPy, поэтому см. также последний раздел).
HDF5: h5py FITS: Astropy
Примеры форматов, которые нельзя прочитать напрямую, но для которых несложно выполнить преобразование, — это форматы, поддерживаемые библиотеками, такими как PIL (способные читать и записывать многие форматы изображений, такие как jpg, png и т. д.).
Общие форматы ASCII
Файлы с разделителями, такие как файлы с разделителями запятыми (csv) и файлы с разделителями табуляцией (tsv), используются программами, такими как Excel и LabView. Функции Python могут читать и анализировать эти файлы построчно. NumPy имеет две стандартные функции для импорта файла с данными с разделителями: numpy.loadtxt и numpy.genfromtxt. Эти функции имеют более сложные варианты использования в разделе Чтение и запись файлов. Пример с simple.csv:
$ cat simple.csv x, y 0, 0 1, 1 2, 4 3, 9
Импорт simple.csv выполняется с помощью numpy.loadtxt:
>>> np.loadtxt('simple.csv', delimiter = ',', skiprows = 1)
array([[0., 0.],
[1., 1.],
[2., 4.],
[3., 9.]])
Более общие ASCII-файлы можно читать с помощью scipy.io и Pandas.
5) Создание массивов из исходных байтов с помощью строк или буферов
Существует множество подходов. Если файл имеет относительно простой формат, то можно написать простую библиотеку ввода-вывода и использовать функцию NumPy fromfile() и метод .tofile() для прямого чтения и записи массивов NumPy (но имейте в виду порядок байтов!). Если существует хорошая C или C++ библиотека, которая считывает данные, вы можете обернуть эту библиотеку с помощью различных техник, хотя это, безусловно, потребует гораздо больше работы и потребует значительно более глубоких знаний для взаимодействия с C или C++.
6) Использование специальных функций библиотек (например, SciPy, pandas и OpenCV)
NumPy — это основная библиотека для контейнеров массивов в стеке Python для научных вычислений. Многие библиотеки Python, включая SciPy, Pandas и OpenCV, используют массивы NumPy nd как общий формат обмена данными. Эти библиотеки могут создавать, обрабатывать и работать с массивами NumPy.
© 2005–2024 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/2.0/user/basics.creation.html