Python numpy array tutorial

1.4.1.5. Indexing and slicing¶

The items of an array can be accessed and assigned to the same way as
other Python sequences (e.g. lists):

>>> a = np.arange(10)
>>> a
array()
>>> a], a2], a-1
(0, 2, 9)

Warning

Indices begin at 0, like other Python sequences (and C/C++).
In contrast, in Fortran or Matlab, indices begin at 1.

The usual python idiom for reversing a sequence is supported:

>>> a)

For multidimensional arrays, indices are tuples of integers:

>>> a = np.diag(np.arange(3))
>>> a
array(,
       ,
       ])
>>> a1, 1
1
>>> a2, 1 = 10 # third line, second column
>>> a
array(,
       ,
       ])
>>> a1
array()

Note

  • In 2D, the first dimension corresponds to rows, the second
    to columns.
  • for multidimensional , is interpreted by
    taking all elements in the unspecified dimensions.

Slicing: Arrays, like other Python sequences can also be sliced:

>>> a = np.arange(10)
>>> a
array()
>>> a293 # 
array()

Note that the last index is not included! :

>>> a)

All three slice components are not required: by default, start is 0,
end is the last and step is 1:

>>> a13
array()
>>> a)
>>> a3:]
array()

A small illustrated summary of NumPy indexing and slicing…

You can also combine assignment and slicing:

>>> a = np.arange(10)
>>> a5:] = 10
>>> a
array()
>>> b = np.arange(5)
>>> a5:] = b)

Exercise: Indexing and slicing

  • Try the different flavours of slicing, using , and
    : starting from a linspace, try to obtain odd numbers
    counting backwards, and even numbers counting forwards.

  • Reproduce the slices in the diagram above. You may
    use the following expression to create the array:

    >>> np.arange(6) + np.arange(, 51, 10),
           ,
           ,
           ,
           ,
           ])
    

Exercise: Array creation

Create the following arrays (with correct data types):

,
 1, 1, 1, 1],
 1, 1, 1, 2],
 1, 6, 1, 1]]

,
 2., , , , ],
 , 3., , , ],
 , , 4., , ],
 , , , 5., ],
 , , , , 6.]]

Par on course: 3 statements for each

Hint: Individual array elements can be accessed similarly to a list,
e.g. or .

Hint: Examine the docstring for .

1.4.1.6. Copies and views¶

A slicing operation creates a view on the original array, which is
just a way of accessing array data. Thus the original array is not
copied in memory. You can use to check if two arrays
share the same memory block. Note however, that this uses heuristics and may
give you false positives.

When modifying the view, the original array is modified as well:

>>> a = np.arange(10)
>>> a
array()
>>> b = a)
>>> np.may_share_memory(a, b)
True
>>> b = 12
>>> b
array()
>>> a   # (!)
array()

>>> a = np.arange(10)
>>> c = a)

>>> np.may_share_memory(a, c)
False

This behavior can be surprising at first sight… but it allows to save both
memory and time.

7.3. Статистика

Над данными в массивах можно производить определенные вычисления, однако, не менее часто требуется эти данные как-то анализировать. Зачастую, в этом случае мы обращаемся к статистике, некоторые функции которой тоже имеются в NumPy. Данные функции могут применять как ко всем элементам массива, так и к элементам, расположенным вдоль определенной оси.

Элементарные статистические функции:

Средние значения элементов массива и их отклонения:

Корреляционные коэфициенты и ковариационные матрицы величин:

Так же NumPy предоставляет функции для вычисления гистограмм наборов данных различной размерности и некоторые другие статистичские функции.

Manipulating NumPy Arrays

NumPy provides a method , which can be used to change the dimensions of the numpy array and modify the original array in place. Here, we show an illustration of using to change the shape of to

>>> c
array()
>>> c.shape
(12,)
>>> c.reshape(4, 3)
array(,
       ,
       ,
       ])

Since numpy operations are designed to be highly optimized, any subarray that is created from an array is still holding the reference to the original array. This means that if the subarray is modified in place, the original array is also modified.

>>> f = e
>>> f
array(,
       ,
       ])
>>> f *= 3
>>> f
array(,
       ,
       ])
>>> e
array(,
       ,
       ])

Here, the original array is also modified with any change in the subarray slice . This is because numpy slices only return a view of the original array.

To ensure that the original array is not modified with any change in the subarray slice, we use numpy method to create a copy of the array and modify the cloned object, instead of dealing with a reference of the original object.

The below snippet shows how deals with this issue.

>>> e
array(,
       ,
       ])
>>> f = e.copy()
>>> f
array(,
       ,
       ])
>>> f = 100
>>> f
array(,
       ,
       ])
>>> e
# No change is reflected in the original array
# We are safe!
array(,
       ,
       ])

Numpy Mode

One thing which should be noted is that there is no in-built function for finding mode using any numpy function. For this, we will use scipy library. First we will create numpy array and then we’ll execute the scipy function over the array.

Syntax

Now we will go over scipy mode function syntax and understand how it operates over a numpy array.

scipy.stats.mode(a, axis=0, nan_policy=’propagate’)

a : array-like – This consists of n-dimensional array of which we have to find mode(s).

axis – int or None (optional) – This is the axis along which to operate. Default is 0. If None, computing mode over the whole array a

nan_policy – {‘propagate’, ‘raise’, ‘omit’} (optional) – This defines how to handle when input contains nan. The following options are available default is propagate which returns nan, raise throws an error and omit performs the calculations ignoring nan values.

As output, two different types of values are produced. First is the mode which is of ndarray type and it consists of array of modal values. The second is count which is again of ndarray type consisting of array of counts for each mode.

Add a column

We can use the append() method of NumPy to insert a column.

Consider the example below where we created a 2-dimensional array and inserted two columns:

import numpy

a = numpy.array(, ])

b = numpy.array(, ])

newArray = numpy.append(a, b, axis = 1)

print(newArray)

The output will be like the following:

If the axis attribute is not used, the output will be like the following:

This is how the structure of the array is flattened.

In NumPy, we can also use the insert() method to insert an element or column. The difference between the insert() and the append() method is that we can specify at which index we want to add an element when using the insert() method but the append() method adds a value to the end of the array.

Consider the example below:

import numpy

a = numpy.array()

newArray = numpy.insert(a, 1, 90)

print(newArray)

The output will be as follows:

Here the insert() method adds the element at index 1. Remember the array index starts from 0.

Основы индексирования и срезы

Существует много способов выбора подмножества данных или элементов
массива. Одномерные массивы — это просто, на первый взгляд они
аналогичны спискам Python:

In : arr = np.arange(10)

In : arr
Out: array()

In : arr
Out: 5

In : arr
Out: array()

In : arr = 12

In : arr
Out: array()

Как видно, если присвоить скалярное значение срезу, как например,
, значение присваивается всем элементам среза. Первым
важным отличием от списков Python заключается в том, что срезы массива
являются представлениями исходного массива. Это означает, что данные
не копируются и любые изменения в представлении будут отражены в
исходном массиве.

Рассмотрим пример. Сначала создадим срез массива :

In : arr_slice = arr

In : arr_slice
Out: array()

Теперь, если мы изменим значения в массиве , то они
отразятся в исходном массиве :

In : arr_slice = 12345

In : arr
Out: 
array()

«Голый» срез присвоит все значения в массиве:

In : arr_slice = 64

In : arr
Out: array()

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

Замечание

Если вы захотите скопировать срез в массив вместо отображения, нужно
явно скопировать массив, например, .

С массивами более высокой размерности существует больше вариантов. В
двумерных массивах каждый элемент это уже не скаляр, а одномерный
массив.

In : arr2d = np.array(, , ])

In : arr2d
Out: array()

Таким образом, к отдельному элементу можно получить доступ
рекурсивно, либо передать разделенный запятыми список
индексов. Например, следующие два примера эквивалентны:

In : arr2d
Out: array()

In : arr2d[]
Out: 3

Если в многомерном массиве опустить последние индексы, то возвращаемый
объект будет массивом меньшей размерности. Например, создадим массив
размерности \( 2 \times 2 \times 3 \):

In : arr3d = np.array(, ], , ]])

In : arr3d
Out: 
array(,
        ],

       ,
        ]])

При этом — массив размерности \( 2 \times 3 \):

In : arr3d[]
Out: 
array(,
       ])

Можно присваивать как скаляр, так и массивы:

In : old_values = arr3d[].copy()

In : arr3d[] = 42

In : arr3d
Out: 
array(,
        ],

       ,
        ]])

In : arr3d[] = old_values

In : arr3d
Out: 
array(,
        ],

       ,
        ]])

Аналогично, возвращает все значения, чьи индексы
начинаются с , формируя одномерный массив:

In : arr3d
Out: array()

Это выражение такое же, как если бы мы проиндексировали в два этапа:

In : x = arr3d

In : x
Out: 
array(,
       ])

In : x[]
Out: array()

Индексирование с помощью срезов

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

In : arr
Out: array()

In : arr
Out: array()

Рассмотрим введенный выше двумерный массив . Получение срезов
этого массива немного отличается от одномерного:

In : arr2d
Out: 
array(,
       ,
       ])

In : arr2d
Out: 
array(,
       ])

Как видно, мы получили срез вдоль оси 0, первой оси. Срез, таким
образом, выбирает диапазон элементов вдоль оси. Выражение
можно прочитать как «выбираем первые две строки массива ».

Можно передавать несколько срезов:

In : arr2d
Out: 
array(,
       ])

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

In : arr2d
Out: array()

In : arr2d
Out: array()

Смотрите рис. .


Рисунок 1: Срезы двумерного массива

1.4.1.2. Creating arrays¶

Manual construction of arrays

  • 1-D:

    >>> a = np.array()
    >>> a
    array()
    >>> a.ndim
    1
    >>> a.shape
    (4,)
    >>> len(a)
    4
    
  • 2-D, 3-D, …:

    >>> b = np.array(, 3, 4, 5]])    # 2 x 3 array
    >>> b
    array(,
           ])
    >>> b.ndim
    2
    >>> b.shape
    (2, 3)
    >>> len(b)     # returns the size of the first dimension
    2
    
    >>> c = np.array(, 2]], , 4]]])
    >>> c
    array(,
            ],
    
           ,
            ]])
    >>> c.shape
    (2, 2, 1)
    

Exercise: Simple arrays

  • Create a simple two dimensional array. First, redo the examples
    from above. And then create your own: how about odd numbers
    counting backwards on the first row, and even numbers on the second?
  • Use the functions , on these arrays.
    How do they relate to each other? And to the attribute of
    the arrays?

Установка NumPy

Я думаю, вы
прониклись уважением к этому пакету, и пришла пора прикоснуться к «святому
граалю». В начале, как всегда, его нужно установить. Сделать это чрезвычайно
просто, достаточно выполнить в терминале команду:

pip install numpy

Не удивляйтесь,
если этот пакет у вас уже установлен, так как он входит в состав многих других
библиотек. Проверить установку можно командой:

import numpy as np

Если такая
программа выполняется без ошибок, то этот «святой грааль» уже присутствует на
вашем устройстве и готов к истязаниям.

У вас здесь уже
может возникнуть вопрос: почему импорт записан в таком виде? А не просто: import
numpy? Можно и так, но тогда в программе все время придется использовать
префикс numpy. Гораздо удобнее писать две буквы «np». Поэтому
общепринятой практикой стало импортирование этого пакета именно в таком виде. Я
буду следовать сложившейся традиции и делать также.

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

В NumPy существует много способов создать массив. Один из наиболее простых — создать массив из обычных списков или кортежей Python, используя функцию numpy.array() (запомните: array — функция, создающая объект типа ndarray):

>>> import numpy as np
>>> a = np.array()
>>> a
array()
>>> type(a)
<class 'numpy.ndarray'>

Функция array() трансформирует вложенные последовательности в многомерные массивы. Тип элементов массива зависит от типа элементов исходной последовательности (но можно и переопределить его в момент создания).

>>> b = np.array(, 4, 5, 6]])
>>> b
array(,
       ])

Можно также переопределить тип в момент создания:

>>> b = np.array(, 4, 5, 6]], dtype=np.complex)
>>> b
array(,
       ])

Функция array() не единственная функция для создания массивов. Обычно элементы массива вначале неизвестны, а массив, в котором они будут храниться, уже нужен. Поэтому имеется несколько функций для того, чтобы создавать массивы с каким-то исходным содержимым (по умолчанию тип создаваемого массива — float64).

Функция zeros() создает массив из нулей, а функция ones() — массив из единиц. Обе функции принимают кортеж с размерами, и аргумент dtype:

>>> np.zeros((3, 5))
array(,
       ,
       ])
>>> np.ones((2, 2, 2))
array(,
        ],

       ,
        ]])

Функция eye() создаёт единичную матрицу (двумерный массив)

>>> np.eye(5)
array(,
       ,
       ,
       ,
       ])

Функция empty() создает массив без его заполнения. Исходное содержимое случайно и зависит от состояния памяти на момент создания массива (то есть от того мусора, что в ней хранится):

>>> np.empty((3, 3))
array(,
       ,
       ])
>>> np.empty((3, 3))
array(,
       ,
       ])

Для создания последовательностей чисел, в NumPy имеется функция arange(), аналогичная встроенной в Python range(), только вместо списков она возвращает массивы, и принимает не только целые значения:

>>> np.arange(10, 30, 5)
array()
>>> np.arange(, 1, 0.1)
array()

Вообще, при использовании arange() с аргументами типа float, сложно быть уверенным в том, сколько элементов будет получено (из-за ограничения точности чисел с плавающей запятой). Поэтому, в таких случаях обычно лучше использовать функцию linspace(), которая вместо шага в качестве одного из аргументов принимает число, равное количеству нужных элементов:

>>> np.linspace(, 2, 9)  # 9 чисел от 0 до 2 включительно
array()

fromfunction(): применяет функцию ко всем комбинациям индексов

Обработка текста в NumPy на примерах

Когда дело доходит до текста, подход несколько меняется. Цифровое представление текста предполагает создание некого , то есть инвентаря всех уникальных слов, которые бы распознавались моделью, а также векторно  (embedding step). Попробуем представить в цифровой форме цитату из стихотворения арабского поэта Антара ибн Шаддада, переведенную на английский язык:

“Have the bards who preceded me left any theme unsung?” 

Перед переводом данного предложения в нужную цифровую форму модель должна будет проанализировать огромное количество текста. Здесь можно обработать небольшой набор данный, после чего использовать его для создания словаря из 71 290 слов.

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

Затем в данной таблице словаря вместо каждого слова мы ставим его :

Однако данные все еще не обладают достаточным количеством информации о модели как таковой. Поэтому перед передачей последовательности слов в модель токены/слова должны быть заменены их векторными представлениями. В данном случае используется 50-мерное векторное представление Word2vec.

Здесь ясно видно, что у массива NumPy есть несколько размерностей . На практике все выглядит несколько иначе, однако данное визуальное представление более понятно для разъяснения общих принципов работы.

Для лучшей производительности модели глубокого обучения обычно сохраняют первую размерность для пакета. Это происходит из-за того, что тренировка модели происходит быстрее, если несколько примеров проходят тренировку параллельно. Здесь особенно полезным будет . Например, такая модель, как BERT, будет ожидать ввода в форме: .

Теперь мы получили числовой том, с которым модель может работать и делать полезные вещи. Некоторые строки остались пустыми, однако они могут быть заполнены другими примерами, на которых модель может тренироваться или делать прогнозы.

(На заметку: Поэма, строчку из которой мы использовали в примере, увековечила своего автора в веках. Будучи незаконнорожденным сыном главы племени от рабыни, Антара ибн Шаддан мастерски владел языком поэзии. Вокруг исторической фигуры поэта сложились мифы и легенды, а его стихи стали частью классической арабской литературы).

1.4.1.7. Fancy indexing¶

Tip

NumPy arrays can be indexed with slices, but also with boolean or
integer arrays (masks). This method is called fancy indexing.
It creates copies not views.

Using boolean masks

>>> np.random.seed(3)
>>> a = np.random.randint(, 21, 15)
>>> a
array()
>>> (a % 3 == )
array()
>>> mask = (a % 3 == )
>>> extract_from_a = amask # or,  a
>>> extract_from_a           # extract a sub-array with the mask
array()

Indexing with a mask can be very useful to assign a new value to a sub-array:

>>> aa % 3 ==  = -1
>>> a
array()

Indexing with an array of integers

>>> a = np.arange(, 100, 10)
>>> a
array()

Indexing can be done with an array of integers, where the same index is repeated
several time:

>>> a]  # note:  is a Python list
array()

New values can be assigned with this kind of indexing:

>>> a] = -100
>>> a
array()

Tip

When a new array is created by indexing with an array of integers, the
new array has the same shape as the array of integers:

>>> a = np.arange(10)
>>> idx = np.array(, 9, 7]])
>>> idx.shape
(2, 2)
>>> aidx
array(,
       ])

The image below illustrates various fancy indexing applications

Exercise: Fancy indexing

  • Again, reproduce the fancy indexing shown in the diagram above.
  • Use fancy indexing on the left and array creation on the right to assign
    values into an array, for instance by setting parts of the array in
    the diagram above to zero.

Операции со срезами matrix в Python

Часто мы работаем не с целым массивом, а с его компонентами. Эти операции выполняются с помощью метода слайс (срез). Он пришел на замену циклу for, при котором каждый элемент подвергался перебору. Метод позволяет получать копии matrix, причём манипуляции выполняются в виде . В данном случае start — индекс элемента, с которого берётся отсчёт, stop — последний элемент, step — размер шага или число пропускаемых значений элемента при каждой итерации. Изначально start равен нулю, stop — индексу последнего элемента, step — единице. Если выполнить операции без аргументов, копирование и добавление списка произойдёт полностью.

Допустим, имеем целочисленный массив otus = . Для копирования и вывода используем otus. В итоге произойдёт вывод последовательности . Но если аргументом станет отрицательное значение, допустим, -2, произойдёт вывод уже других данных:

otus-2]; //4 

Возможны и другие операции. Например, если добавить ещё одно двоеточие, будет указан шаг копируемых элементов. Таким образом, otus позволит вывести матрицу .

Если ввести отрицательное значение, к примеру, отсчёт начнётся с конца, и в результате произойдёт вывод . Остаётся добавить, что метод среза позволяет гибко работать с матрицами и вложенными списками в Python.

Хотите узнать гораздо больше? Записывайтесь на курс «Разработчик Python»!

Append NumPy array to another

You can append a NumPy array to another NumPy array by using the append() method.

Consider the following example:

import numpy

a = numpy.array()

b = numpy.array()

newArray = numpy.append(a, b)

print("The new array = ", newArray)

The output will be as follows:

In this example, a NumPy array “a” is created and then another array called “b” is created. Then we used the append() method and passed the two arrays. As the array “b” is passed as the second argument, it is added at the end of the array “a”.

As we saw, working with NumPy arrays is very simple. NumPy arrays are very essential when working with most machine learning libraries. So, we can say that NumPy is the gate to artificial intelligence.

max/ min:

Next, we have some more operations in numpy such as to find the minimum, maximum as well the sum of the numpy array. Let’s go ahead in python numpy tutorial and execute it practically.

import numpy as npa= np.array()print(a.min())print(a.max())print(a.sum())Output - 1 3 6

You must be finding these pretty basic, but with the help of this knowledge, you can perform a lot bigger tasks as well. Now, let’s understand the concept of axis in python numpy.

As you can see in the figure, we have a numpy array 2*3. Here the rows are called as axis 1 and the columns are called as axis 0. Now you must be wondering what is the use of these axis?

Suppose you want to calculate the sum of all the columns, then you can make use of axis. Let me show you practically, how you can implement axis in your PyCharm:

a= np.array()print(a.sum(axis=0))Output - 

Therefore, the sum of all the columns are added where 1+3=4, 2+4=6 and 3+5=8. Similarly, if you replace the axis by 1, then it will print where all the rows get added.

Транспонирование и изменение формы матриц в numpy

Нередки случаи, когда нужно повернуть матрицу. Это может потребоваться при вычислении скалярного произведения двух матриц. Тогда возникает необходимость наличия совпадающих размерностей. У массивов NumPy есть полезное свойство под названием , что отвечает за транспонирование матрицы.

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

Еще больше размерностей NumPy

NumPy может произвести все вышеперечисленные операции для любого количества размерностей. Структура данных, расположенных центрально, называется , или n-мерным массивом.

В большинстве случаев для указания новой размерности требуется просто добавить запятую к параметрам функции NumPy:

Shell

array(,
,
],

,
,
],

,
,
],

,
,
]])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

array(1.,1.,

1.,1.,

1.,1.,

1.,1.,

1.,1.,

1.,1.,

1.,1.,

1.,1.,

1.,1.,

1.,1.,

1.,1.,

1.,1.)

Транспонирование массивов и замена осей

Транспонирование — это особый способ изменения формы массива, который
возвращает представление исходных данных без их копирования. Массивы
имеют метод , а также специальный атрибут :

In : arr = np.arange(15).reshape((3, 5))

In : arr
Out: 
array(,
       ,
       ])

In : arr.T
Out: 
array(,
       ,
       ,
       ,
       ])

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

In : arr = np.random.randn(6, 3)

In : arr
Out: 
array(,
       ,
       ,
       ,
       ,
       ])

In : np.dot(arr.T, arr)
Out: 
array(,
       ,
       ])

Для массивов большей размерности метод принимает кортеж с
номерами осей, задающий перестановку осей:

In : arr = np.arange(16).reshape((2, 2, 4))

In : arr
Out: 
array(,
        ],

       ,
        ]])

In : arr.transpose((1, , 2))
Out: 
array(,
        ],

       ,
        ]])

Здесь оси были переупорядочены следующим образом: вторая ось стала
первой, первая ось — второй, а последняя осталась без изменений.

Простое транспонирование с помощью является частным случаем
замены осей. Массивы имеют метод , который получает пару
номеров осей и переставляет указанные оси.

In : arr.swapaxes(1, 2)
Out: 
array(,
        ,
        ,
        ],

       ,
        ,
        ,
        ]])

Метод возвращает представление данных без копирования.

  • ← Prev
  • Next →

7.1.1. Значения -inf, inf и nan

Возможно вы обратили внимание на то, что когда мы вычисляли натуральный логарифм массива, среди значений которого был ноль, не появилось абсолютно никакой ошибки, а сам логарифм стал равен значению (минус бесконечность). Убедимся в этом еще раз:. Более того, в NumPy мы даже можем делить на ноль:

Более того, в NumPy мы даже можем делить на ноль:

NumPy предупредил нас о том, что встретил деление на ноль, но тем не менее выдал ответ (плюс бесконечность). Дело в том, что с математической точки зрения все абсолютно верно — если вы что-то делите на бесконечно малое значение то в результате получете значение, которое окажется бесконечно большим. Если результатом математической операции является плюс или минус бесконечность, то логичнее выдать значение или чем выдавать ошибку.

В NumPy есть еще одно специальное значение — . Данное значение выдается тогда, когда результат вычислений не удается определить:

Заметьте, что NumPy нас просто предупредил о том, что ему попалось недопустимое значение, но ошибки не возникло. Дело в том, что в реальных вычислениях значения , или встречается очень часто, поэтому появление этого значения проще обрабатывать специальными методами (функции и ), чем постоянно лицезреть сообщения об ошибках.

Новичкам, довольно трудно привыкнуть, к тому что в недрах компьютера вся арифметика на самом деле является двоичной и с этим связано очень много казусов. Во первых не совсем понятно, когда ждать появления значений и :

Число 1.633123935319537e+16 появилось потому что в NumPy выполняются арифметические, а не символьные вычисления, т. е. число π хранится в памяти компьютера не как знание о том, что это математическая константа с бесконечным количеством десятичных знаков после запятой, а как обычное число с десятичной точкой (десятичная дробь) равная числу π с очень маленькой, но все же, погрешностью:

NumPy отличает предельные случаи, когда вычисления выполнить невозможно, например, деление на ноль. В таких случаях появляются значения , и . Если из-за самых незначительных погрешностей вычисления все же возможны, то NumPy их обязательно выполнит. В этих случаях вместо значений или у вас будут появляться самые маленькие или самые большие числа, которые возможно представить на вашем компьютере.

Тем не менее и на этом сюрпризы не заканчиваются. Если число 1.633123935319537e+16 является самым больши, которое может появиться при вычислениях, оно вполне ожидаемо должно появиться в самых разных ситуациях. Например:

То, есть какая-то, длинная арифметика все же доступна — очень хорошая новость, для лбителей криптографии и теории чисел. Но иногда:

В заключение могу лишь сказать, что все предельные случаи требуют кардинальных решений. Некоторые решения имеются в самом NumPy, некоторые предоставляют другие пакеты. Если вам необходимы точные решения, то лучше обратиться к системам компьютерной алгебры и символьных вычислений, например пакету SymPy — маленький, но мощьный пакет Python для символьных вычислений. Если вы решили отправиться в самые дебри теории чисел, алгебры и криптографии, то лучшим решением окажется программа GAP. Программа GAP не является программой Python, но имеет Python интерфейс в замечательной программе Sage, которая определенно заслуживает вашего внмания.

Базовые операции

Математические операции над массивами выполняются поэлементно. Создается новый массив, который заполняется результатами действия оператора.

>>> import numpy as np
>>> a = np.array()
>>> b = np.arange(4)
>>> a + b
array()
>>> a - b
array()
>>> a * b
array()
>>> a  b  # При делении на 0 возвращается inf (бесконечность)
array()
<string>:1: RuntimeWarning: divide by zero encountered in true_divide
>>> a ** b
array()
>>> a % b  # При взятии остатка от деления на 0 возвращается 0
<string>:1: RuntimeWarning: divide by zero encountered in remainder
array()

Для этого, естественно, массивы должны быть одинаковых размеров.

>>> c = np.array(, 4, 5, 6]])
>>> d = np.array(, 3, 4], 5, 6]])
>>> c + d
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2,3) (3,2)

Также можно производить математические операции между массивом и числом. В этом случае к каждому элементу прибавляется (или что вы там делаете) это число.

>>> a + 1
array()
>>> a ** 3
array()
>>> a < 35  # И фильтрацию можно проводить
array(, dtype=bool)

NumPy также предоставляет множество математических операций для обработки массивов:

>>> np.cos(a)
array()
>>> np.arctan(a)
array()
>>> np.sinh(a)
array()

Полный список можно посмотреть здесь.

Многие унарные операции, такие как, например, вычисление суммы всех элементов массива, представлены также и в виде методов класса ndarray.

>>> a = np.array(, 4, 5, 6]])
>>> np.sum(a)
21
>>> a.sum()
21
>>> a.min()
1
>>> a.max()
6

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector