NumPy: введение в учебник по NumPy

Python

Введение

NumPy — это библиотека Python с открытым исходным кодом, в основном используемая для анализа данных и научных вычислений.По сути, NumPy можно рассматривать как основу для вычислений данных Python, потому что многие отличные платформы для анализа данных и машинного обучения используют NumPy внизу. Например: Pandas, SciPy, Matplotlib, scikit-learn, scikit-image и т. д.

Библиотека NumPy в основном содержит многомерные массивы и матричные структуры данных. Он предоставляет методы для ndarray (объекта n-мерного массива) для эффективной работы с ним. NumPy можно использовать для выполнения различных математических операций над массивами. И предоставляет огромную библиотеку высокоуровневых математических функций, которые могут работать с этими массивами и матрицами.

Установить NumPy

Есть много способов следить за NumPy:

pip install numpy

Если вы используете conda, вы можете:

conda install numpy

Или используйте Anaconda напрямую — это набор пакетов для анализа данных.

Массив и список

В Python есть тип данных под названием List, который может хранить различные типы объектов. Нет ничего плохого в том, чтобы сделать это в приложении, но если речь идет о научных вычислениях, мы хотим, чтобы типы элементов в массиве были согласованными, поэтому у нас есть Array в NumPy.

NumPy может быстро создавать массивы и работать с данными в них.

Массив в NumPy намного быстрее, чем List в Python, и занимает меньше места в памяти.

Взгляните на разницу в производительности между ними:

In [1]: import numpy as np
   ...: my_arr = np.arange(1000000)
   ...: my_list = list(range(1000000))
   ...: %time for _ in range(10): my_arr2 = my_arr * 2
   ...: %time for _ in range(10): my_list2 = [x * 2 for x in my_list]
   ...:
CPU times: user 12.3 ms, sys: 7.88 ms, total: 20.2 ms
Wall time: 21.4 ms
CPU times: user 580 ms, sys: 172 ms, total: 752 ms
Wall time: 780 ms

В приведенном выше примере данных, содержащих один миллион операций, выполненных 2, вы можете видеть, что эффективное использование Python NumPy несколько раз очень сильно влияет на производительность, если эффективность приведет к большим проектам данных.

Создать массив

В приведенном выше примере мы создали массив с помощью метода np.arange.

Мы также можем создать массив через список, который может быть одномерным списком или многомерным списком:

>>> a = np.array([1, 2, 3, 4, 5, 6])

>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

Как и к списку, к массиву также можно получить доступ по индексу:

>>> print(a[0])
[1 2 3 4]

Далее мы вводим некоторые часто используемые существительные:

  • vector— представляет собой одномерный массив
  • matrix— представляет двумерный массив
  • tensor- представляет массив из трех измерений или выше

В NumPy измерения также называютсяaxes.

Давайте рассмотрим несколько других способов создания массива:

Самый простой — это np.array, о котором мы уже упоминали в предыдущем примере.

Чтобы быстро создать массив нулей, мы можем использовать нули:

>>> np.zeros(2)
array([0., 0.])

или оба заполнены 1:

>>> np.ones(2)
array([1., 1.])

Вы также можете создавать пустые массивы:

In [2]: np.empty(2)
Out[2]: array([0.        , 2.00389455])

Обратите внимание, что содержимое в пустом методе не обязательно пустое, а случайно заполнено данными, поэтому после того, как мы используем пустое значение для создания массива, мы должны не забыть перезаписать содержимое. Преимущество использования пустого в том, что скорость создания выше.

Вы также можете заполнить массив в пределах диапазона:

In [3]: np.arange(10)
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Интервалы могут быть указаны:

In [4]: np.arange(1,10,2)
Out[4]: array([1, 3, 5, 7, 9])

Используйте linspace для создания равномерно разделенных массивов:

In [5]: np.linspace(0, 10, num=5)
Out[5]: array([ 0. ,  2.5,  5. ,  7.5, 10. ])

Тип содержимого массива, созданный по умолчанию, — np.float64, мы также можем переключить его на целочисленный: np.int64

In [6]: x = np.ones(2, dtype=np.int64)

In [7]: x
Out[7]: array([1, 1])

Операции с массивами

sort

Мы можем отсортировать массив, используя sort:

In [8]: arr = np.array([2, 1, 5, 3, 7, 4, 6, 8])

In [10]: np.sort(arr)
Out[10]: array([1, 2, 3, 4, 5, 6, 7, 8])

==sort== предназначен для сортировки элементов в массиве, помимо сортировки существуют и другие методы сортировки.

Вы также можете использовать argsort, косвенный метод сортировки, который возвращает индекс отсортированного исходного массива:

In [11]: x = np.array([10, 5, 6])

In [12]: np.argsort(x)
Out[12]: array([1, 2, 0])

Выше мы выполнили ==argsort== для массива, который после сортировки должен вернуть 5, 6, 10. Индекс 5 равен 1, индекс 6 равен 2, а индекс 10 равен 0, поэтому возвращаем 1, 2, 0.

==lexsort==, как и argsort, является косвенным методом сортировки, который возвращает отсортированный индекс, разница в том, что lexsort может выполнять сортировку по нескольким ключам.

surnames =    ('Hertz',    'Galilei', 'Hertz')
first_names = ('Heinrich', 'Galileo', 'Gustav')
ind = np.lexsort((first_names, surnames))
ind
array([1, 2, 0])

Вышеупомянутая лексическая сортировка сначала сортирует по фамилиям, а затем по именам.

Порядок сортировки lexsort — от конца к началу. То есть последний пришедший ключ сортируется первым.

==searchsorted== используется для поиска значения индекса вставляемого элемента, например:

np.searchsorted([1,2,3,4,5], 3)
2
np.searchsorted([1,2,3,4,5], 3, side='right')
3
np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3])
array([0, 5, 1, 2])

==partition== разделяет сортируемые данные, например:

a = np.array([3, 4, 2, 1])
np.partition(a, 3)
array([2, 1, 3, 4])

Первый параметр – это массив, а второй – элемент ссылки, который необходимо отделить. Положение элемента ссылки совпадает с положением сортировки. Другие элементы меньшего размера, чем элемент ссылки, помещаются впереди, а те, что больше опорный элемент размещается спереди, сзади.

Вы также можете разделить на несколько элементов:

np.partition(a, (1, 3))
array([1, 2, 3, 4])

concatenate

concatenate используется для объединения нескольких массивов.

>>> a = np.array([1, 2, 3, 4])
>>> b = np.array([5, 6, 7, 8])

>>> np.concatenate((a, b))
array([1, 2, 3, 4, 5, 6, 7, 8])

Вы также можете объединять многомерные массивы:

>>> x = np.array([[1, 2], [3, 4]])
>>> y = np.array([[5, 6]])
>>> np.concatenate((x, y), axis=0)
array([[1, 2],
       [3, 4],
       [5, 6]])

Статистика

ndarray.ndimИспользуйте для подсчета размеров массива:

>>> array_example = np.array([[[0, 1, 2, 3],
...                            [4, 5, 6, 7]],
...
...                           [[0, 1, 2, 3],
...                            [4, 5, 6, 7]],
...
...                           [[0 ,1 ,2, 3],
...                            [4, 5, 6, 7]]])
>>> array_example.ndim
3

ndarray.sizeЧтобы подсчитать количество элементов в массиве:

>>> array_example.size
24

ndarray.shapeФорма выходного массива:

>>> array_example.shape
(3, 2, 4)

Объясните, что приведенный выше массив представляет собой массив 3 * 2 * 4.

reshape

Используйте reshape для восстановления массива.

>>> a = np.arange(6)
>>> print(a)
[0 1 2 3 4 5]

>>> b = a.reshape(3, 2)
>>> print(b)
[[0 1]
 [2 3]
 [4 5]]

Выше мы преобразовали одномерный массив в массив 3*2.

reshape также может принимать несколько параметров:

>>> numpy.reshape(a, newshape=(1, 6), order='C')
array([[0, 1, 2, 3, 4, 5]])

Первый параметр — это реконструируемый массив, второй параметр — новая форма, порядок может принимать три значения: C, F или A.

C означает сортировку по индексу C, а F означает сортировку по индексу Fortran. А означает автоматический выбор.

В Fortran при перемещении элементов двумерного массива, хранящегося в памяти, первый индекс изменяется быстрее всего. Матрица сохраняет по одному столбцу за раз при переходе к следующей строке при изменении первого индекса. С другой стороны, в C последний индекс изменяется быстрее всего.

добавить измерение

np.newaxis может добавить измерение в существующий массив:

>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> a.shape
(6,)

>>> a2 = a[np.newaxis, :]
>>> a2.shape
(1, 6)

>>> col_vector = a[:, np.newaxis]
>>> col_vector.shape
(6, 1)

Вы также можете использовать expand_dims, чтобы указать положение оси:

>>> b = np.expand_dims(a, axis=1)
>>> b.shape
(6, 1)

>>> c = np.expand_dims(a, axis=0)
>>> c.shape
(1, 6)

индекс и срез

Индексы массива и срезы похожи на списки в Python:

>>> data = np.array([1, 2, 3])

>>> data[1]
2
>>> data[0:2]
array([1, 2])
>>> data[1:]
array([2, 3])
>>> data[-2:]
array([2, 3])

Кроме того, массивы также поддерживают более мощные операции с индексами:

>>> a = np.array([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

>>> print(a[a < 5])
[1 2 3 4]

Выше мы нашли значения всех элементов в a, которые меньше 5.

In [20]: a<5
Out[20]:
array([[ True,  True,  True,  True],
       [False, False, False, False],
       [False, False, False, False]])

Вы можете видеть, что a

Точно так же мы можем выбрать все элементы больше 5:

>>> five_up = (a >= 5)
>>> print(a[five_up])
[ 5  6  7  8  9 10 11 12]

Выберите все числа, которые делятся на 2:

>>> divisible_by_2 = a[a%2==0]
>>> print(divisible_by_2)
[ 2  4  6  8 10 12]

Вы также можете использовать операторы & и |:

>>> c = a[(a > 2) & (a < 11)]
>>> print(c)
[ 3  4  5  6  7  8  9 10]

Вы также можете использовать ненулевое значение для вывода информации индекса, которая соответствует условиям:

In [23]: a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

In [24]: b = np.nonzero(a < 5)

In [25]: b
Out[25]: (array([0, 0, 0, 0]), array([0, 1, 2, 3]))
  
>>> print(a[b])
[1 2 3 4]

В кортеже, возвращенном выше, первое значение представляет номер строки, а второе значение представляет столбец.

Создать массив из существующих данных

Мы можем использовать нарезку, индексирование, np.vstack(), np.hstack(), np.hsplit(), .view(), copy() для создания массива из существующих данных.

В предыдущем примере мы видели, что можем использовать списки и срезы для создания новых массивов:

>>> a = np.array([1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
>>> arr1 = a[3:8]
>>> arr1
array([4, 5, 6, 7, 8])

Два существующих массива могут быть сложены вертикально или горизонтально:

>>> a1 = np.array([[1, 1],
...                [2, 2]])

>>> a2 = np.array([[3, 3],
...                [4, 4]])

>>> np.vstack((a1, a2))
array([[1, 1],
       [2, 2],
       [3, 3],
       [4, 4]])

>>> np.hstack((a1, a2))
array([[1, 1, 3, 3],
       [2, 2, 4, 4]])

Используйте hsplit, чтобы разбить большой массив на несколько меньших:

>>> x = np.arange(1, 25).reshape(2, 12)
>>> x
array([[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12],
       [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]])

>>> np.hsplit(x, 3)
[array([[1,  2,  3,  4],
        [13, 14, 15, 16]]), array([[ 5,  6,  7,  8],
        [17, 18, 19, 20]]), array([[ 9, 10, 11, 12],
        [21, 22, 23, 24]])]

арифметические операции

Добавление массива:

>>> data = np.array([1, 2])
>>> ones = np.ones(2, dtype=int)
>>> data + ones
array([2, 3])

Другие операции:

>>> data - ones
array([0, 1])
>>> data * data
array([1, 4])
>>> data / data
array([1., 1.])

сумма массива:

>>> a = np.array([1, 2, 3, 4])

>>> a.sum()
10

Если вы суммируете многомерный массив, вам необходимо указать размеры:

>>> b = np.array([[1, 1], [2, 2]])
>>> b.sum(axis=0)
array([3, 3])

>>> b.sum(axis=1)
array([2, 4])

Другие полезные операции

Другие полезные операции перечислены здесь:

>>> data.max()
2.0
>>> data.min()
1.0
>>> data.sum()
3.0

Для двумерных массивов sum по умолчанию суммирует все элементы, а min также находит наименьший из всех элементов:

>>> a = np.array([[0.45053314, 0.17296777, 0.34376245, 0.5510652],
...               [0.54627315, 0.05093587, 0.40067661, 0.55645993],
...               [0.12697628, 0.82485143, 0.26590556, 0.56917101]])

>>> a.sum()
4.8595784

>>> a.min()
0.05093587

Мы также можем указать размеры:

>>> a.min(axis=0)
array([0.12697628, 0.05093587, 0.26590556, 0.5510652 ])

матрица

Матрица представляет собой массив 2*2:

>>> data = np.array([[1, 2], [3, 4]])
>>> data
array([[1, 2],
       [3, 4]])

Матрицы также могут выполнять статистические операции:

>>> data.max()
4
>>> data.min()
1
>>> data.sum()
10

По умолчанию накапливаются все элементы, мы также можем указать конкретное измерение накопления:

>>> data.max(axis=0)
array([3, 4])
>>> data.max(axis=1)
array([2, 4])

Матричные операции:

>>> data = np.array([[1, 2], [3, 4]])
>>> ones = np.array([[1, 1], [1, 1]])
>>> data + ones
array([[2, 3],
       [4, 5]])

Если операция многомерная и низкоразмерная, то для трансляции низкомерной будет использоваться встроенный механизм трансляции:

>>> data = np.array([[1, 2], [3, 4], [5, 6]])
>>> ones_row = np.array([[1, 1]])
>>> data + ones_row
array([[2, 3],
       [4, 5],
       [6, 7]])

генерировать случайные числа

В машинном обучении очень важной функцией является генерация случайных чисел. Давайте посмотрим, как генерировать случайные числа в Numpy.

>>> rng = np.random.default_rng(0)
>>> rng.random(3)
array([0.63696169, 0.26978671, 0.04097352])

>>> rng.random((3, 2))
array([[0.01652764, 0.81327024],
       [0.91275558, 0.60663578],
       [0.72949656, 0.54362499]])  # may vary
       
>>> rng.integers(5, size=(2, 4))
array([[2, 1, 1, 0],
       [0, 0, 0, 4]])  # may vary

unique

np.uniqueВы можете подсчитать уникальные значения массива:

>>> a = np.array([11, 11, 12, 13, 14, 15, 16, 17, 12, 13, 11, 14, 18, 19, 20])

>>> unique_values = np.unique(a)
>>> print(unique_values)
[11 12 13 14 15 16 17 18 19 20]

Вы также можете вернуть индекс или количество:

>>> unique_values, indices_list = np.unique(a, return_index=True)
>>> print(indices_list)
[ 0  2  3  4  5  6  7 12 13 14]
>>> unique_values, occurrence_count = np.unique(a, return_counts=True)
>>> print(occurrence_count)
[3 2 2 2 1 1 1 1 1 1]

Также работает для матриц:

>>> a_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [1, 2, 3, 4]])

>>> unique_values = np.unique(a_2d)
>>> print(unique_values)
[ 1  2  3  4  5  6  7  8  9 10 11 12]

Если вы хотите получить уникальные строки или столбцы, вы можете передать параметр оси:

>>> unique_rows = np.unique(a_2d, axis=0)
>>> print(unique_rows)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

матричное преобразование

Мы можем использовать транспонирование, чтобы поменять местами строки и столбцы матрицы:

>>> arr = np.arange(6).reshape((2, 3))
>>> arr
array([[0, 1, 2],
       [3, 4, 5]])

>>> arr.transpose()
array([[0, 3],
       [1, 4],
       [2, 5]])

перевернуть массив

Используйте flip, чтобы перевернуть массив:

>>> arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
>>> reversed_arr = np.flip(arr)
>>> print('Reversed Array: ', reversed_arr)
Reversed Array:  [8 7 6 5 4 3 2 1]

Если это двумерный массив:

>>> arr_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

>>> reversed_arr = np.flip(arr_2d)
>>> print(reversed_arr)
[[12 11 10  9]
 [ 8  7  6  5]
 [ 4  3  2  1]]

По умолчанию строки и столбцы меняются местами, мы также можем поменять местами только строки или столбцы:

>>> reversed_arr_rows = np.flip(arr_2d, axis=0)
>>> print(reversed_arr_rows)
[[ 9 10 11 12]
 [ 5  6  7  8]
 [ 1  2  3  4]]

>>> reversed_arr_columns = np.flip(arr_2d, axis=1)
>>> print(reversed_arr_columns)
[[ 4  3  2  1]
 [ 8  7  6  5]
 [12 11 10  9]]

Вы также можете изменить только строку или столбец:


>>> arr_2d[1] = np.flip(arr_2d[1])
>>> print(arr_2d)
[[ 1  2  3  4]
 [ 8  7  6  5]
 [ 9 10 11 12]]

>>> arr_2d[:,1] = np.flip(arr_2d[:,1])
>>> print(arr_2d)
[[ 1 10  3  4]
 [ 8  7  6  5]
 [ 9  2 11 12]]

сгладить и распутать

flatten может сделать массив одномерным:

>>> x = np.array([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

>>> x.flatten()
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

Массив после сглаживания не имеет ничего общего с исходным массивом, модифицируем массив после сглаживания без изменения содержимого предыдущего массива:

>>> a1 = x.flatten()
>>> a1[0] = 99
>>> print(x)  # Original array
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
>>> print(a1)  # New array
[99  2  3  4  5  6  7  8  9 10 11 12]

Но с ravel модификации нового массива также изменят исходный массив:

>>> a2 = x.ravel()
>>> a2[0] = 98
>>> print(x)  # Original array
[[98  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
>>> print(a2)  # New array
[98  2  3  4  5  6  7  8  9 10 11 12]

сохранить и загрузить

Объекты NumPy можно сохранять и загружать из файлов с помощью сохранения и загрузки:

>>> a = np.array([1, 2, 3, 4, 5, 6])

>>> np.save('filename', a)

>>> b = np.load('filename.npy')

Если вы хотите сохранить текст, вы можете использовать np.savetxt:

>>> csv_arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])

>>> np.savetxt('new_file.csv', csv_arr)

>>> np.loadtxt('new_file.csv')
array([1., 2., 3., 4., 5., 6., 7., 8.])

CSV

NumPy имеет специальные методы для работы с файлами CSV:

>>> import pandas as pd

>>> # If all of your columns are the same type:
>>> x = pd.read_csv('music.csv', header=0).values
>>> print(x)
[['Billie Holiday' 'Jazz' 1300000 27000000]
 ['Jimmie Hendrix' 'Rock' 2700000 70000000]
 ['Miles Davis' 'Jazz' 1500000 48000000]
 ['SIA' 'Pop' 2000000 74000000]]

>>> # You can also simply select the columns you need:
>>> x = pd.read_csv('music.csv', usecols=['Artist', 'Plays']).values
>>> print(x)
[['Billie Holiday' 27000000]
 ['Jimmie Hendrix' 70000000]
 ['Miles Davis' 48000000]
 ['SIA' 74000000]]

Эта статья была включена вwoohoo.floydpress.com/01-python-вы…

Самая популярная интерпретация, самая глубокая галантерея, самые краткие уроки и множество трюков, о которых вы не знаете, ждут вас!

Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: «Программируйте эти вещи», разбирайтесь в технологиях, лучше поймите себя!