Spec-Zone.ru › NumPy 1.21

Создание массивов

См. также

Процедуры создания массивов

Введение

Существует 6 основных механизмов для создания массивов:

  1. Преобразование из других структур Python (например, списков и кортежей)
  2. Встроенные функции NumPy для создания массивов (например, arange, ones, zeros и т. д.)
  3. Копирование, объединение или изменение существующих массивов
  4. Чтение массивов из диска, в стандартных или пользовательских форматах
  5. Создание массивов из сырых байтов с использованием строк или буферов
  6. Использование специальных функций библиотек (например, random)

Вы можете использовать эти методы для создания nd-массивов или структурированных массивов. В данном документе будут рассмотрены общие методы создания nd-массивов.

1) Преобразование последовательностей Python в массивы NumPy

Массивы NumPy могут быть определены с использованием последовательностей Python, таких как списки и кортежи. Списки и кортежи определяются с использованием [...] и (...), соответственно. Списки и кортежи могут определять создание nd-массивов:

  • список чисел создаст одномерный массив,
  • список списков создаст двумерный массив,
  • вложенные списки создадут массивы большей размерности. В общем случае любой массив в NumPy называется ndarray.
>>> 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 присваивания, вы можете получить нежелательное переполнение, как в примере

>>> a = np.array([127, 128, 129], dtype=np.int8)
>>> a
array([ 127, -128, -127], dtype=int8)

8-битовое знаковое целое число представляет целые числа от -128 до 127. Присваивание int8 массиву целых чисел вне этого диапазона приводит к переполнению. Этот момент часто неправильно понимают. Если вы выполняете вычисления с несовместимыми dtypes, вы можете получить нежелательные результаты, например:

>>> a = array([2, 3, 4], dtype = np.uint32)
>>> b = 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 создаёт массивы либо в 64-битовых знакомых целых числах, либо с плавающей точкой двойной точности, int64 и float, соответственно. Если вы ожидаете, что ваши массивы будут определённого типа, то вам необходимо указать dtype при создании массива.

2) Встроенные функции NumPy для создания массивов

NumPy имеет более 40 встроенных функций для создания массивов, как указано в Процедурах создания массивов. Эти функции можно разделить на примерно три категории, в зависимости от размерности массива, который они создают:

  1. Одномерные массивы
  2. Двумерные массивы
  3. 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) определяет единичную матрицу 2-го порядка. Элементы, где 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.  , 0.  , 1.  ],
       [0.25, 0.5 , 1.  ],
       [1.  , 1.  , 1.  ],
       [2.25, 1.5 , 1.  ],
       [4.  , 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 создаст массив, заполненный нулями, с указанной формой. Тип данных по умолчанию - 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 создаст массив, заполненный единицами. Она идентична 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, чтобы вы могли воспроизвести эти псевдослучайные числа:

>>> import numpy.random.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 5 6] 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 выполняется с помощью 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 ndarrays в качестве общего формата для обмена данными. Эти библиотеки могут создавать, работать с и использовать массивы NumPy.

© 2005–2022 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.21/user/basics.creation.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API