Создание массивов#
Импортируем NumPy и начинаем работу:
import numpy as np
Преобразование в массив из стандартных коллекций Python (list
, tuple
и ряда других) осуществляется функцией np.array
.
Одномерный массив:
np.array([1, 2, 3, 4])
array([1, 2, 3, 4])
Двумерный массив:
np.array([(1, 2), (3, 4)])
array([[1, 2],
[3, 4]])
Трёхмерный массив:
np.array(
[
[(1, 2), (3, 4)],
[(5, 6), (7, 8)]
]
)
array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
Можно явно указать тип чисел (данных) массива.
Делается это с помощью указания параметра dtype
:
np.array([1, 2, 3], dtype=float)
array([1., 2., 3.])
Для создания одномерных массивов в NumPy имеются такие функции, как np.linspace
и np.arange
.
Функция np.arange
создаёт массив по заданным началу, концу и шагу - np.arange(start, stop, step)
:
# Указан только конец интервала stop
# Начало по умолчанию принято за 0
np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# start, stop
np.arange(2, 10)
array([2, 3, 4, 5, 6, 7, 8, 9])
# start, stop, step
np.arange(2, 10, 2)
array([2, 4, 6, 8])
# массив float (т.к. шаг имеет тип float)
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])
Warning
По умолчанию конец интервала (3 в последнем случае) не входит в итоговый массив. Так получается, как правило, из-за ошибок округления компьютером вещественных чисел. Всегда стоит об этом помнить.
Функция np.linspace
создаёт массив по заданным началу, концу и числу точек, равномерно расположенных от начального до конечного значения:
# start, stop, num
np.linspace(1, 4, 6)
array([1. , 1.6, 2.2, 2.8, 3.4, 4. ])
Note
При использовании np.linspace
в отличие от np.arange
последнее значение всегда входит в созданный массив.
Для создания двумерных массивов имеются следующие функции: np.eye
, np.diag
и np.vander
.
Функция np.eye
инициализирует единичную матрицу.
В общем случае можно сгенерировать и прямоугольную матрицу \(\mathbf{A}\), у которой все элементы равны нулю, кроме единиц, стоящих в псевдодиагонали, где индекс строки \(i\) совпадает с индексом столбца \(j\), то есть \(a_{i j} = 1\) при \(i = j\) и \(a_{i j} = 0\) при \(i \neq j\).
# Единичная матрица 3x3
np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
Обратите внимание, что тип данных по умолчанию float
.
Иной тип данных необходимо указывать явно.
# То же, но целочисленный вариант
np.eye(3, dtype=int)
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.]])
Функция np.diag
по переданному одномерному массиву (списку, кортежу) создаёт диагональную матрицу, на диагонали которой расположены элементы переданного массива:
np.diag([1, 2, 3])
array([[1, 0, 0],
[0, 2, 0],
[0, 0, 3]])
Здесь тип данных по умолчанию определяется по типу переданных данных.
В данном случае был передан список целых чисел (int
).
Можно указать тип данных и вручную через dtype=...
.
# С указанием смещения от главной диагонали
np.diag([1, 2, 3], 1)
array([[0, 1, 0, 0],
[0, 0, 2, 0],
[0, 0, 0, 3],
[0, 0, 0, 0]])
np.diag
не только создаёт квадратную матрицу с диагональными элементами, но может и выделять диагональные элементы из заданной матрицы.
# Получение диагонали матрицы
a = np.array([(1, 2), (3, 4)])
np.diag(a)
array([1, 4])
Функция np.vander
несколько специфична - она создаёт матрицу Вандермонда.
С помощью этой функции по переданному массиву a
длины \(m\) создаётся матрица с \(n\) столбцами, каждый столбец которой является переданным массивом a
, каждый элемент которого возведён в степень \(n - j - 1\), где \(j\) - индекс столбца:
# (a, n)
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]])
Для создания массивов произвольной размера (формы, shape) применяются функции np.zeros
, np.ones
, np.full
и random
.
Note
О генераторах случайных чисел, в т.ч. в NumPy, см. Использование генераторов псевдослучайных чисел.
Функция np.zeros
создаёт массив заданной формы, заполненный нулями.
Note
Тип данных по умолчанию - float
.
# Одномерный массив
np.zeros(3)
array([0., 0., 0.])
# Двумерный массив
# (обратите внимание, что форма передаётся как кортеж,
# список или массив, а не просто через запятую)
np.zeros((3, 5))
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
# То же, но целочисленный вариант
np.zeros((3, 5), dtype=int)
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
# Трёхмерный массив
np.zeros((2, 3, 5))
array([[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]])
Функция np.ones
устроена тем же образом и делает то же самое, но заполняет массив единицами:
np.ones((2, 3))
array([[1., 1., 1.],
[1., 1., 1.]])
Функция np.full
возвращает массив заданной формы, заполненный заданным значением.
Тип данных определяется типом переданного значения либо указывается явно.
# (форма, значение)
np.full((2, 3), 3.5)
array([[3.5, 3.5, 3.5],
[3.5, 3.5, 3.5]])
np.full(3, -1)
array([-1, -1, -1])
Чтобы сгенерировать массив, заполненный псевдослучайными числами используется генератор таких чисел. Стандартный NumPy-генератор псевдослучайных чисел создаётся просто:
rg = np.random.default_rng()
С помощью этого генератора возможно создавать различные массивы (подробнее в Использование генераторов псевдослучайных чисел):
# Матрица, заполненная случайными числами от 0 до 1
rg.random((5, 3))
array([[0.83350103, 0.25405848, 0.83745866],
[0.46880512, 0.13421931, 0.13031926],
[0.45732792, 0.6692817 , 0.32947936],
[0.21377765, 0.0461932 , 0.54430177],
[0.20746495, 0.492854 , 0.45904645]])
NumPy также имеет функцию создания массива индексов np.indices
.
Создаваемый ею массив индексов полезен для операций с массивами на регулярной сетке.
np.indices((3, 3))
array([[[0, 0, 0],
[1, 1, 1],
[2, 2, 2]],
[[0, 1, 2],
[0, 1, 2],
[0, 1, 2]]])
Создать массив из генератора позволяет функция np.fromiter
:
np.fromiter((x for x in range(1, 10, 2)), int)
array([1, 3, 5, 7, 9])
Обратите внимание, что данной функции необходимо указывать тип данных, т.к. сам генератор эту информацию не предоставляет.
Создавать массив, используя обычную Python-функцию, позволяет функция np.fromfunction
:
# (создающая функция, форма массива)
np.fromfunction(lambda i, j: i, (2, 2))
array([[0., 0.],
[1., 1.]])
np.fromfunction(lambda i, j: j, (2, 2))
array([[0., 1.],
[0., 1.]])
np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])
def gen_array(i, j):
return i * j
np.fromfunction(gen_array, (3, 3), dtype=int)
array([[0, 0, 0],
[0, 1, 2],
[0, 2, 4]])
Создание подобных массивов#
Рассмотренные выше функции np.zeros
, np.ones
и np.full
имеют близкие по результату функции np.zeros_like
, np.ones_like
и np.full_like
.
Новые функции на вход принимают не форму нового массива, а другой массив, из которого берут и форму, и тип данных.
# Пусть есть массив со случайными целыми числами
a = rg.integers(-10, 11, size=(3, 5))
a
array([[-6, 1, -4, -5, -6],
[ 8, 5, 6, 4, 4],
[ 5, 5, -4, -7, -1]])
Тогда мы можем создать подобные ему массивы.
np.zeros_like(a)
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
# Скопируем массив
b = a.copy()
# И у нового изменим тип данных на float
b.dtype = float
# Как следствие, изменится и тип данных подобного массива
np.ones_like(b)
array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
np.full_like(a, 77)
array([[77, 77, 77, 77, 77],
[77, 77, 77, 77, 77],
[77, 77, 77, 77, 77]])
np.full_like(a, 0.1)
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
Заметьте, вместо массива, заполненного 0.1, получили массив нулей.
Это случилось потому, что тип данных в исходном массиве a
есть int
.
Соответственно, дробная часть у 0.1 была отброшена.
Автоматически тип данных подобного массива не изменяется, а назначается таким же, как у исходного массива. Изменить это можно, явно указав тип данных:
np.full_like(a, 0.1, dtype=float)
array([[0.1, 0.1, 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, 0.1, 0.1]])
Создание массивов из файлов#
NumPy имеет средства для чтения данных из файлов стандартных (для NumPy) и произвольных форматов.
Для чтения данных из текстового файла (текстовым является не только .txt файл) используется функция np.loadtxt
.
Пусть есть CSV-файл simple.csv
со следующим содержимым:
x,y
0,0
1,1
2,4
3,9
Создать NumPy-массив на его основе несложно:
# Прочитать заданный файл,
# разделителем значений считать запятую,
# не читать первую строку файла (заголовок CSV)
np.loadtxt(
"simple.csv",
delimiter=",",
skiprows=1
)
array([[0., 0.],
[1., 1.],
[2., 4.],
[3., 9.]])
См. также#
Более подробная информация на официальном сайте NumPy.
Подробная информация о чтении и записи файлов в NumPy.