Как найти наименьший общий делитель python

В данном уроке мы узнаем, как найти наименьшее общее кратное (НОК) и наибольший общий делитель (НОД) с помощью языка программирования Python.

Но прежде чем мы начнем, давайте разберем, что обозначает Least Common Multiple (LCM) — наименьшее общее кратное.

НОК: наименьшее общее кратное

Это понятие арифметики и системы счисления. НОК двух целых чисел a и b обозначается НОК(a,b). Это наименьшее натуральное число, которое делится и на «а», и на «b».

Например: у нас есть два целых числа 4 и 6. Найдем НОК:

  • Кратные 4:
 
4, 8, 12, 16, 20, 24, 28, 32, 36,... and so on... 
  • Кратные 6:
 
6, 12, 18, 24, 30, 36, 42,... and so on.... 

Общие кратные 4 и 6 — это просто числа, которые есть в обоих списках:

 
12, 24, 36, 48, 60, 72,.... and so on.... 

НОК — это наименьший общий множитель, поэтому он равен 12.

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

Пример:

 
# defining a function to calculate LCM 
def calculate_lcm(x, y): 
    # selecting the greater number 
    if x > y: 
        greater = x 
    else: 
        greater = y 
    while(True): 
        if((greater % x == 0) and(greater % y == 0)): 
            lcm = greater 
            break 
        greater += 1 
    return lcm   
 
# taking input from users 
num1 = int(input("Enter first number: ")) 
num2 = int(input("Enter second number: ")) 
# printing the result for the users 
print("The L.C.M. of", num1,"and", num2,"is", calculate_lcm(num1, num2)) 

Выход:

Enter first number: 3 
Enter second number: 4 
The L.C.M. of 3 and 4 is 12 

Объяснение:

Эта программа сохраняет два числа в num1 и num2 соответственно. Эти числа передаются в функцию calculate_lcm(). Функция возвращает НОК двух чисел.

Внутри функции мы сначала определили большее из двух чисел, поскольку наименьшее общее кратное может быть больше или равно наибольшему числу. Затем мы используем бесконечный цикл while, чтобы перейти от этого числа и дальше.

На каждой итерации мы проверяли, идеально ли делят оба числа число. Если это так, мы сохранили число как НОК и вышли из цикла. В противном случае число увеличивается на 1, и цикл продолжается.

НОД: наибольший общий делитель

В этом разделе мы разберем, как найти Highest Common Factor (HCF) — наибольший общий делитель (НОД) в языке программирования Python.

Наибольший общий делитель двух или более целых чисел, когда хотя бы одно из них не равно нулю, является наибольшим положительным целым числом, которое без остатка делит целые числа. Например, НОД 8 и 12 равен 4.

Например:

У нас есть два целых числа 8 и 12. Найдем наибольший общий делитель.

  • Делители числа 8:
 
1, 2, 4, 8 
  • Делители числа 12:
 
1, 2, 3, 4, 6, 12 

НОД 8 и 12 равны 4.

Теперь давайте рассмотрим пример, основанный на нахождении НОД двух заданных чисел.

Пример:

 
# defining a function to calculate HCF 
def calculate_hcf(x, y): 
    # selecting the smaller number 
    if x > y: 
        smaller = y 
    else: 
        smaller = x 
    for i in range(1,smaller + 1): 
        if((x % i == 0) and(y % i == 0)): 
            hcf = i 
    return hcf 
 
# taking input from users 
num1 = int(input("Enter first number: ")) 
num2 = int(input("Enter second number: ")) 
# printing the result for the users 
print("The H.C.F. of", num1,"and", num2,"is", calculate_hcf(num1, num2)) 

Выход:

Enter first number: 8 
Enter second number: 12 
The H.C.F. of 8 and 12 is 4 

Объяснение:

В приведенном выше фрагменте кода два целых числа, хранящиеся в переменных num1 и num2, передаются в функцию calculate_hcf(). Функция вычисляет НОД для этих двух чисел и возвращает его.

Внутри функции мы должны определить меньшее число, поскольку НОД может быть меньше или равен наименьшему числу. Затем мы использовали цикл for, чтобы перейти от 1 к этому числу.

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

1196-1017cookie-checkНахождение НОК и НОД в Python — примеры

Функции относящиеся к теории чисел.

В этом разделе представлены функции относящиеся к теории чисел.

Содержание:

  • Факториал числа,
  • Наибольший общий делитель целых чисел,
  • Функция math.frexp(),
  • Функция math.ldexp(),
  • Абсолютное значение числа,
  • Остаток от деления,
  • Получить дробную и целую часть числа,
  • Получить точную сумму элементов списка,
  • Получить число x со знаком числа y,
  • Сравнение в пределах указанной точности,
  • Наименьшее общее кратное целых чисел,
  • Следующее значение float после x по направлению к y,
  • Наименьший значащий бит числа float.

math.factorial(x):

Функция math.factorial() возвращает факториал указанного числа x.

>>> import math
>>> math.factorial(5)
120

Данная функция всегда возвращает число типа int и поддерживает длинную арифметику, т.е. величина обрабатываемого числа x и возвращаемого результата ограничивается только возможностями компьютера.

Если x не является целым числом или если x является отрицательным, то будет вызвано исключение ValueError.

Изменено в Python 3.9. Не рекомендуется передавать числа с плавающей запятой с целыми значениями (например, 5.0).

math.gcd(*integers):

Функция math.gcd() возвращает наибольший общий делитель указанных целочисленных аргументов *integers.

>>> import math
>>> math.gcd(3886, 9048)
# 58

# проверяем
>>> 3886/58, 9048/58
# (67.0, 156.0)
  • Если какой-либо из аргументов не равен нулю, то возвращаемое значение является наибольшим положительным целым числом, которое является делителем всех аргументов:
  • Если все аргументы равны нулю, то возвращаемое значение равно 0.
  • функция math.gcd() вызванная без аргументов возвращает 0.

Указанные числа должны быть целыми типа int, но могут быть как положительными, так и отрицательными:

>>> import math
>>> math.gcd(-4, -8)
# 4
>>> math.gcd(-4, -8.8)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'float' object cannot be interpreted as an integer

Изменено в Python 3.9: Добавлена ​​поддержка произвольного количества аргументов. Раньше поддерживалось только два аргумента.

math.frexp(x):

Функция math.frexp() возвращает кортеж из двух чисел (m, e) таких что x == m*2**e.

>>> import math
>>> math.frexp(123)
# (0.9609375, 7)
>>> 0.9609375*2**7
# 123.0

Число m принадлежит к типу float и всегда является таким, что 0.5 <= abs(m) < 1, даже для тех случаев, когда значением x является произвольная степень двойки. Число e всегда целое число int:

>>> math.frexp(0.25)
# (0.5, -1)
>>> math.frexp(64)
# (0.5, 7)

Если x равен 0, то будет возвращено (0.0, 0).

Данная функция используется тогда, когда представление чисел типа float не должно зависеть от архитектуры машины.

math.ldexp(x, i):

Функция math.ldexp() возвращает значение равное x*2**i, т.е. является обратной к функции math.frexp().

>>> import math
>>> math.ldexp(3, 4)
# 48.0
>>> math.ldexp(0.125, 8)
# 32.0

math.fabs(x):

Функция math.fabs() возвращает абсолютное значение, модуль числа x. Результат всегда тип float.

>>> import math
>>> math.fabs(-3)
3.0

Данная функция в отличии от встроенной функции abs() не обрабатывает комплексные числа.

math.fmod(x):

Функция math.fmod() возвращает остаток от деления числа x на число y, вычисленный так, как это определено в библиотеке math языка C.

>>> import math
>>> math.fmod(2.23, 0.2)
0.02999999999999986

Данная функция направлена на то, что бы результат был максимально приближен к значению x - n*y для некоторого целого числа n, что бы этот результат имел тот же знак, что и x, что бы разность x - n*y == abs(y).

Для чисел типа float данная функция является предпочтительнее чем команда x%y, которая в свою очередь является предпочтительной для чисел типа int. Так как для некоторых случаев, например при x = -1e-100 и x = 1e100, команда x%y может вообще выдать неправильный результат.

math.modf(x):

Функция math.modf() возвращает кортеж из двух чисел (f, w) где f это дробная, а w — целая часть числа x. Результат всегда имеет тип float.

>>> import math
>>> math.modf(3)
# (0.0, 3.0)
>>> math.modf(3.14)
# (0.14000000000000012, 3.0)

math.fsum(iterable):

Функция math.fsum() возвращает точную сумму значений в итерируемой последовательности iterable. Возвращаемый результат всегда типа float.

>>> import math
>>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
# 0.9999999999999999
>>> math.fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
# 1.0

Может показаться, что эта сумма будет точной всегда, но на самом деле это не так:

>>> math.fsum([0.3, 0.3, 0.3])
0.8999999999999999

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

math.copysign(x, y):

Функция math.copysign() возвращает число c абсолютным значением x, но со знаком числа y. Возвращаемый результат всегда типа float

>>> import math
>>> math.copysign(14, -12)
# -14.0
>>> math.copysign(-14, 12)
# 14.0

На платформах, которые поддерживают нули со знаком функция math.copysign(1.0, -0.0) возвращает -1.0.

math.isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0):

Функция math.isclose() возвращает True если в пределах указанной точности, числа a и b близки настолько, что их можно считать равными.

>>> import math
>>> x = 7
>>> y = 7.000000000000001
>>> x==y
# False
>>> math.isclose(x, y)
# True

Считать числа близкими или нет, определяют два аргумента rel_tol и abs_tol.

Аргумент rel_tol это относительный допуск, определяемый как максимально допустимая разница между числами a и b относительно большего из них по модулю. По умолчанию rel_tol=1e-09, что гарантирует, что числа a и b будут одинаковы, в пределах 9 десятичных цифр. Чтобы числа считались равными, если они, допустим, отличаются меньше чем на 0.1%, то достаточно установить rel_tol=0.001, но в любом случае данный параметр, должен быть больше нуля:

>>> y = 7.000001
>>> math.isclose(y, 6.999, rel_tol=0.001)
# True

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

Данная функция эквивалентна команде abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol). Значения inf, -inf считаются близкими только сами к себе, а NaN не является близким ни к одному значению, включая само NaN.

math.lcm(*integers):

Функция math.lcm() возвращает наименьшее общее кратное указанных целочисленных аргументов *integers.

  • Если все аргументы отличны от нуля, то возвращаемое значение является наименьшим положительным целым числом, кратным всем аргументам.
  • Если какой-либо из аргументов равен нулю, то возвращается значение 0.
  • Функция math.lcm(), вызванная без аргументов возвращает 1.

Новое в Python 3.9.

math.nextafter(x, y):

Функция math.nextafter() возвращает следующее значение float после x по направлению к y.

Если x равно y, то функция возвращает y.

Примеры:

  • math.nextafter(x, math.inf) идет вверх: в сторону положительной бесконечности.
  • math.nextafter(x, -math.inf) идет вниз: в сторону минус бесконечности.
  • math.nextafter(x, 0.0) стремится к нулю.
  • math.nextafter(x, math.copysign(math.inf, x)) уходит от нуля.

Новое в Python 3.9.

Смотрите также математическую функцию math.ulp().

math.ulp(x):

Функция math.isclose() возвращает значение наименьшего значащего бита числа float x.

  • Если xNaN (не число), то вернет x.
  • Если x отрицательный, то вернет ulp(-x).
  • Если x — положительная бесконечность, то вернет x.
  • Если x равен нулю, то вернет наименьшее положительное денормализованное представимое число float (меньше минимального положительного нормализованного числа float, sys.float_info.min).
  • Если x равен наибольшему положительному представимому числу float, то вернет значение младшего значащего бита x, так что первое число float меньше x будет x - ulp(x).
  • В противном случае (x — положительное конечное число) вернет значение младшего значащего бита x, так что первое число float больше x равно x + ulp(x).

ULP означает «Единица на последнем месте».

Новое в Python 3.9.

Смотрите также математическую функцию math.nextafter().

Как найти НОК или НОД в python 3.9 в списке из n кол-ва чисел? (Ввод чисел пользователем)
(н: math.gcd([1 , 2 , 3])

задан 26 окт 2021 в 16:22

Romalik Normalik's user avatar

4

список из нескольких чисел можно получить следующим образом:

data = list(map(int, input().split()))

весь код таким образом будет выглядеть так:

import math

data = list(map(int, input().split()))

gcd = math.gcd(*data)
lcm = math.lcm(*data)

print(gcd, lcm)

ответ дан 26 окт 2021 в 16:42

Zhihar's user avatar

ZhiharZhihar

36.9k4 золотых знака25 серебряных знаков67 бронзовых знаков

1

print ('a = ', end = '')

a = int (input ())

print ('b = ', end = '')

b = int (input ())

p = a * b

while a != 0 and b != 0:

    if a > b:

        a = a % b

    else:

        b = b % a

nod = a + b

nok = p // nod

print ('GCD:', nok)
print ('LDM:', nod)

ответ дан 26 окт 2021 в 16:29

D3vzer1's user avatar

2

НОД – это математический термин, обозначающий наибольший общий делитель, который может идеально разделить два числа. НОД также известен как наибольший общий фактор(HCF).

Например, HCF / GCD двух чисел 54 и 24 равен 6. Поскольку 6 – это наибольший общий делитель, который полностью делит 54 и 24.

Разберемся как найти НОД двух чисел в Python. НОД двух чисел в Python

НОД с использованием функции gcd()

gcd() в python – это встроенная функция, предлагаемая математическим модулем для поиска наибольшего общего делителя двух чисел.

Синтаксис:

 
gcd(a, b) 

Где a и b – два целых числа, которые передаются в качестве аргумента функции gcd().

Давайте создадим программу для печати НОД двух чисел, используя встроенную функцию math.gcd() в python.

math_fun.py

 
# create a program to print the gcd of two number in python using the math.gcd() function. 
import math 
print(" GCD of two number 0 and 0 is ", math.gcd(0, 0)) #math.gcd(a, b), a and b are the two integer number 
print(" GCD of two number 0 and 48 is ", math.gcd(0, 48)) 
a = 60 # assign the number to variable a 
b = 48 # assign the number to variable b 
print(" GCD of two number 60 and 48 is ", math.gcd(a, b)) # pass the variable a and b to math.gcd() function. 
print(" GCD of two number 48 and -12 is ", math.gcd(48, -12)) # pass the integer number 
print(" GCD of two number -24 and -18 is ", math.gcd(-24, -18)) 
print(" GCD of two number -60 and 48 is ", math.gcd(-60, 48)) 

Выход:

Выход

В приведенном выше примере функция math.gcd() генерирует НОД двух заданных чисел. В функции gcd() a и b передаются в качестве аргумента, который возвращает наибольший общий делитель двух целых чисел, полностью разделяя числа.

НОД с использованием рекурсии

Рекурсия – это функция, потребляющая память, определенная в Python, которая вызывает себя через самореферентное выражение. Это означает, что функция будет постоянно вызывать и повторять себя до тех пор, пока не будет выполнено определенное условие для возврата наибольшего общего делителя числа.

Псевдокод алгоритма

Шаг 1: Возьмите два входа, x и y, от пользователя.

Шаг 2: Передайте входной номер в качестве аргумента рекурсивной функции.

Шаг 3: Если второе число равно нулю(0), возвращается первое число.

Шаг 4: В противном случае он рекурсивно вызывает функцию со вторым числом в качестве аргумента, пока не получит остаток, который делит второе число на первое число.

Шаг 5: Вызовите или назначьте gcd_fun() переменной.

Шаг 6: Отобразите НОД двух чисел.

Шаг 7: Выйдите из программы.

Разберемся с программой для нахождения НОД двух чисел с помощью рекурсии.

gcdRecur.py

 
# write a program to understand the GCD of two number in python using the recursion. 
def gcd_fun(x, y): 
    if(y == 0): # it divide every number 
        return x  # return x 
    else: 
        return gcd_fun(y, x % y) 
x =int(input("Enter the first number: ")) # take first no.  
y =int(input("Enter the second number: ")) # take second no.  
num = gcd_fun(x, y) # call the gcd_fun() to find the result 
print("GCD of two number is: ") 
print(num) # call num 

Выход:

Нахождение НОД двух чисел с помощью рекурсии

Нахождение НОД с помощью цикла

Давайте создадим программу для нахождения НОД двух чисел в Python с помощью циклов.

gcdFile.py

 
def GCD_Loop( a, b): 
    if a > b:  # define the if condition 
        temp = b 
    else: 
        temp = a 
    for i in range(1, temp + 1): 
        if(( a % i == 0) and(b % i == 0 )): 
            gcd = i 
    return gcd 
x = int(input(" Enter the first number: ") ) # take first no.  
y =int(input(" Enter the second number: ")) # take second no.  
num = GCD_Loop(x, y) # call the gcd_fun() to find the result 
print("GCD of two number is: ") 
print(num) # call num 

Выход:

Нахождение НОД с помощью цикла

Как мы видим в приведенной выше программе, мы берем два значения в качестве входных и передаем эти числа в функцию GCD_Loop(), чтобы вернуть GCD.

Алгоритм Евклида

Алгоритм Евклида – эффективный метод нахождения наибольшего общего делителя двух чисел. Это самый старый алгоритм, который делит большее число на меньшее и берет остаток. Опять же, он делит меньшее число от остатка, и этот алгоритм непрерывно делит число, пока остаток не станет 0.

Например, предположим, что мы хотим вычислить HCF двух чисел, 60 и 48. Затем мы делим 60 на 48; он возвращает остаток 12. Теперь мы снова делим число 24 на 12, а затем он возвращает остаток 0. Таким образом, мы получаем HCF равным 12.

Псевдокод алгоритма Евклида

Шаг 1: Есть два целых числа, например a и b.

Шаг 2: Если a = 0, то НОД(a, b) равен b.

Шаг 3: Если b = 0, НОД(a, b) равен a.

Шаг 4: Найти mod b.

Шаг 5: Предположим, что a = b и b = R.

Шаг 6: Повторяйте шаги 4 и 3, пока mod b не станет равным или большим 0.

Шаг 7: GCD = b и затем распечатайте результат.

Шаг 8: Остановите программу.

Найдем HCF или GCD двух чисел, используя алгоритм Евклида в python.

Euclid.py

 
# Create a program to find the GCD of two number in python using the Euclid's Algorithm. 
def find_hcf(a,b): 
    while(b): 
        a, a = b, a % b 
        return a 
a = int(input(" Enter the first number: ") ) # take first no.  
b = int(input(" Enter the second number: ")) # take second no.  
num = find_hcf(a, b) # call the find_hcf() to get the result 
print("  The HCF of two number a and b is ") 
print(num) # call num 

Выход:

Алгоритм Евклида для НОД

Изучаю Python вместе с вами, читаю, собираю и записываю информацию опытных программистов.

Давайте рассмотрим библиотеки math и numpy для решения математических задач.

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

Библиотека math

Библиотека math является стандартной в Python и содержит много полезных математических функций и констант. Официальная документация Python выделяет следующие виды функций этого модуля:

  • Функции теории чисел и функции представления. Рассмотрим некоторые из них:

    • math.comb(n, k) — возвращает количество сочетаний из n элементов по k элементам без повторений и без учёта порядка. Определим, сколькими способами можно выбрать 3 объекта из множества в 12 объектов (порядок не важен):

      import math
      
      print(math.comb(12, 3))  # 220
      
    • math.factorial(x) — возвращает факториал целого неотрицательного числа x:

      print(math.factorial(5))  # 120
      
    • math.gcd(*integers) — возвращает наибольший общий делитель (НОД) для чисел-аргументов. Возможность определения НОДа для более чем двух чисел появилась в Python версии 3.9:

      print(math.gcd(120, 210, 360))  # 30
      
    • math.lcm(*integers) — возвращает наименьшее общее кратное (НОК) для чисел-аргументов. Функция появилась в Python версии 3.9:

      print(math.lcm(10, 20, 30, 40))  # 120
      
    • math.perm(n, k=None) — возвращает количество размещений из n элементов по k элементам без повторений и с учётом порядка. Если значение аргумента k не задано, то возвращается количество перестановок множества из n элементов:

      print(math.perm(4, 2))  # 12
      print(math.perm(4))  # 24
      
    • math.prod(iterable, start=1) — возвращает произведение элементов итерируемого объекта iterable. Если iterable пустой, то возвращается значение именованного аргумента start:

      print(math.prod(range(10, 21)))  # 6704425728000
      
  • Степенные и логарифмические функции. Некоторые из функций:

    • math.exp(x) — возвращает значение экспоненциальной функции ex:

      print(math.exp(3.5))  # 33.11545195869231
      
    • math.log(x, base) — возвращает значение логарифма от x по основанию base. Если значение аргумента base не задано, то вычисляется натуральный логарифм. Вычисление производится по формуле log(x) / log(base):

      print(math.log(10))  # 2.302585092994046
      print(math.log(10, 2))  # 3.3219280948873626
      
    • math.pow(x, y) — возвращает значение x в степени y. В отличие от операции **, происходит преобразование обоих аргументов в вещественные числа:

      print(math.pow(2, 10))  # 1024.0
      print(math.pow(4.5, 3.7))  # 261.1477575641718
      
  • Тригонометрические функции. Доступны функции синус (sin(x)), косинус (cos(x)), тангенс (tan(x)), арксинус (asin(x)), арккосинус (acos(x)), арктангенс (atan(x)). Обратите внимание: угол задаётся и возвращается в радианах. Имеются особенные функции:

    • math.dist(p, q) — возвращает Евклидово расстояние между точками p и q, заданными как итерируемые объекты одной длины:

      print(math.dist((0, 0, 0), (1, 1, 1)))  # 1.7320508075688772
      
    • math.hypot(*coordinates) — возвращает длину многомерного вектора с координатами, заданными в позиционных аргументах coordinates, и началом в центре системы координат. Для двумерной системы координат функция возвращает длину гипотенузы прямоугольного треугольника по теореме Пифагора:

      print(math.hypot(1, 1, 1))  # 1.7320508075688772
      print(math.hypot(3, 4))  # 5.0
      
  • Функции преобразования угла. Доступны функции:

    • math.degrees(x) — преобразует угол из радианов в градусы:

      print(round(math.sin(math.radians(30)), 1))  # 0.5
      
    • math.radians(x) — преобразует угол из градусов в радианы.

      print(round(math.degrees(math.asin(0.5)), 1))  # 30.0
      
  • Гиперболические функции. Доступны функции acosh(x), asinh(x), atanh(x), cosh(x), sinh(x), tanh(x).

  • Специальные функции. Среди специальных функций интерес представляет Гамма-функция. Она описывает гладкую непрерывную функцию f(x) = (x — 1)!, график которой проходит через точки, соответствующие значениям функции факториала для целых чисел. Другими словами, гамма-функция интерполирует значения факториала для вещественных чисел:

    print(math.gamma(3))  # 2.0
    print(math.gamma(3.5))  # 3.323350970447842
    print(math.gamma(4))  # 6.0
    

В библиотеке math можно воспользоваться значениями числа пи (math.pi) и экспоненты (math.e).

Библиотека numpy

Язык программирования Python удобен для быстрого создания программ с целью проверки какой-либо идеи. Однако зачастую его используют и в решении научных задач, а также при анализе больших данных и машинном обучении.
Возникает вопрос: каким образом может быстро обрабатывать много данных интерпретируемая, а не скомпилированная программа?
Оказывается, что в решении некоторых математических задач программы на Python могут быть такими же быстрыми, как и программы, созданные на компилируемых языках.

Существенную прибавку в скорости обеспечивает библиотека numpy (Numerical Python, читается как «нампАй»). Библиотека numpy частично написана на языках С и «Фортран», благодаря чему и работает быстро. Таким образом, numpy сочетает в себе вычислительную мощность языков С и «Фортран» и простоту синтаксиса Python.

Библиотека numpy является нестандартной библиотекой.

Нестандартные модули можно установить в Python несколькими способами. Мы рассмотрим самый простой — установку из репозитория PyPI (Python Package Index). Репозиторий — коллекция дополнительных библиотек для Python, хранящаяся на сервере. В настоящий момент количество библиотек в репозитории составляет более 400 тысяч.

Для установки библиотек из репозитория необходимо подключение к сети Интернет, а далее нужно выполнить команду в консоли (терминале):

pip install <название библиотеки>

Установим библиотеку numpy командой:

pip install numpy

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

Successfully installed numpy

Для импорта numpy обычно используют следующий код:

import numpy as np

В программе мы сможем обращаться к numpy по новому имени — np. Это упростит чтение кода. Такой импорт широко используется сообществом программистов, поэтому стоит его придерживаться, чтобы ваш код был понятен каждому.

Библиотека numpy работает с объектами-массивами, которые способны хранить много значений и быть многомерными. При этом, в отличие от списков, массивы могут хранить только значения одного типа. За счёт этого массивы в numpy занимают меньше памяти и работают быстрее, чем списки.

Создать массив можно разными способами. Один из них — использовать функцию array() для преобразования списка в массив. Для доступа к элементам массива необходимо указать индекс элемента в квадратных скобках. Индексация начинается с нуля:

import numpy as np

a = np.array([1, 2, 3, 4])
b = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
print(f"a[0] = {a[0]}")
print(f"b[0] = {b[0]}")

Вывод программы:

a[0] = 1
b[0] = [1 2]

В нашем примере массив a имеет размерность, равную 1. Размерность массива b равна 2. В терминологии numpy массив a имеет одну ось (термин «axis» из документации) длиной четыре элемента, а массив b имеет две оси: первая имеет длину 4, а длина второй оси равна 2.

Массивы numpy являются объектами класса ndarray. Наиболее важными атрибутами класса ndarray являются:

  • ndarray.ndim — размерность (количество осей) массива;
  • ndarray.shape — кортеж, значения которого содержат количество элементов по каждой из осей массива;
  • ndarray.size — общее количество элементов массива;
  • ndarray.dtype — объект, описывающий тип данных элементов массива;
  • ndarray.itemsize — размер памяти в байтах, занимаемый одним элементом массива.
import numpy as np

a = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
print(f"a.ndim = {a.ndim}, a.shape = {a.shape}, a.size = {a.size}, a.dtype = {a.dtype}")

Вывод программы:

a.ndim = 2, a.shape = (4, 2), a.size = 8, a.dtype = int32

Встроенные в numpy типы данных аналогичны типам данных в языке программирования С. Например, в предыдущем примере мы создали массив со значениями типа int32, то есть целые числа со знаком (отрицательные и положительные) и размером занимаемой памяти 32 бита. Из ограничения в размере памяти для типов данных в numpy следует то, что массивы каждого типа данных могут хранить значения из определённого диапазона. Например, для int32 этот числовой диапазон составляет от -2 147 483 648 до 2 147 483 647.

Покажем на примере, что произойдёт, если попытаться записать значение не из диапазона для типа данных. Для этого создадим массив типа uint8 — целые числа без знака размером 8 бит. Диапазон значений для этого типа от 0 до 255. Тип данных можно указать через именованный аргумент dtype при создании массива:

import numpy as np

a = np.array([1, 2, 3], dtype="uint8")
a[0] = 256
print(a)

Вывод программы:

[0 2 3]

Значение элемента не вышло за пределы диапазона, а было взято с его начала.

В numpy существуют и другие встроенные типы данных. С ними можно ознакомиться в документации.

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

Рассмотрим пример:

import numpy as np

a = np.array([1, 2.5, 3])
print(a)
print(a.dtype)
b = np.array(['text', 1, 2.5])
print(b)
print(b.dtype)

Вывод программы:

[1.  2.5 3. ]
float64
['text' '1' '2.5']
<U32

В примере для массива a был выбран тип данных float64, так как исходный список содержит вещественное число. Для массива b был выбран тип данных <U32, который может хранить строки в кодировке Unicode длиной 32 символа. Такой тип данных был выбран, поскольку в исходной коллекции есть элемент-строка.

Для создания массива из нулей используется функция np.zeros(), которая принимает кортеж с количеством чисел, соответствующим количеству осей массива, а значения в кортеже — количество элементов по каждой из осей.

import numpy as np

a = np.zeros((4, 3))
print(a)
print()
a = np.zeros((4, 3), dtype="int32")
print(a)

Вывод программы:

[[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.zeros(), только из элементов-единиц.

import numpy as np

a = np.ones((4, 3))
print(a)

Вывод программы:

[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]

Функция np.eye() создаёт единичную матрицу, то есть массив с единицами на главной диагонали и нулевыми остальными элементами:

import numpy as np

a = np.eye(5, 5, dtype="int8")
print(a)

Вывод программы:

[[1 0 0 0 0]
 [0 1 0 0 0]
 [0 0 1 0 0]
 [0 0 0 1 0]
 [0 0 0 0 1]]

Для создания массива, заполненного значениями из диапазона, используется функция np.arange(). Эта функция похожа на стандартную функцию range(), но возвращает массив и может создавать диапазон значений из вещественных чисел.

import numpy as np

a = np.arange(1, 10)
print(a)
print()
a = np.arange(1, 5, 0.4)
print(a)

Вывод программы:

[1 2 3 4 5 6 7 8 9]

[1.  1.4 1.8 2.2 2.6 3.  3.4 3.8 4.2 4.6]

Функция np.linspace() создаёт массив из заданного количества вещественных равномерно распределённых значений из указанного диапазона.

import numpy as np

a = np.linspace(1, 5, 10)  # задаётся начало, конец диапазона и количество значений
print(a)

Вывод программы:

[1.         1.44444444 1.88888889 2.33333333 2.77777778 3.22222222
 3.66666667 4.11111111 4.55555556 5.        ]

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

import numpy as np

a = np.zeros((4, 3), dtype="uint8")
print(a)
print()
a = a.reshape((2, 6))
print(a)

Вывод программы:

[[0 0 0]
 [0 0 0]
 [0 0 0]
 [0 0 0]]

[[0 0 0 0 0 0]
 [0 0 0 0 0 0]]

Метод resize() меняет размерность исходного массива:

import numpy as np

a = np.zeros((4, 3), dtype="uint8")
print(a)
print()
a.resize((2, 2, 3))
print(a)

Вывод программы:

[[0 0 0]
 [0 0 0]
 [0 0 0]
 [0 0 0]]

[[[0 0 0]
  [0 0 0]]

 [[0 0 0]
  [0 0 0]]]

Если при изменении размерности в функции reshape() указать значение -1 по одной или нескольким осям, то значения размерности рассчитаются автоматически:

import numpy as np

a = np.zeros((4, 3), dtype="uint8")
print(a)
print()
a = a.reshape((2, 3, -1))
print(a)

Вывод программы:

[[0 0 0]
 [0 0 0]
 [0 0 0]
 [0 0 0]]

[[[0 0]
  [0 0]
  [0 0]]

 [[0 0]
  [0 0]
  [0 0]]]

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

import numpy as np

a = np.array([9, 8, 7])
b = np.array([1, 2, 3])
print(a + b)
print(a - b)
print(a * b)
print(a / b)

Вывод программы:

[10 10 10]
[8 6 4]
[ 9 16 21]
[9.         4.         2.33333333]

Для умножения матриц используется операция @ или функция dot:

import numpy as np

a = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])
b = np.array([[0, 0, 1],
              [0, 1, 0],
              [1, 0, 0]])
print(a @ b)

Вывод программы:

[[3 2 1]
 [6 5 4]
 [9 8 7]]

Матрицы можно транспонировать функцией transpose() и поворачивать функцией rot90(). При повороте можно указать направление поворота вторым аргументом:

import numpy as np

a = np.arange(1, 13).reshape(4, 3)
print(a)
print("Транспонирование")
print(a.transpose())
print("Поворот вправо")
print(np.rot90(a))
print("Поворот влево")
print(np.rot90(a, -1))

Вывод программы:

[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
Транспонирование
[[ 1  4  7 10]
 [ 2  5  8 11]
 [ 3  6  9 12]]
Поворот вправо
[[ 3  6  9 12]
 [ 2  5  8 11]
 [ 1  4  7 10]]
Поворот влево
[[10  7  4  1]
 [11  8  5  2]
 [12  9  6  3]]

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

import numpy as np

a = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print(a.sum())
print(a.min())
print(a.max())

Вывод программы:

45
1
9

Дополнительно в указанных функциях можно указать номер оси (индексация с 0), на которой будет работать функция:

import numpy as np

a = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])
print(a.sum(axis=0))  # сумма чисел в каждом столбце
print(a.sum(axis=1))  # сумма чисел в каждой строке
print(a.min(axis=0))  # минимум по столбцам
print(a.max(axis=1))  # максимум по строкам

Вывод программы:

[12 15 18]
[ 6 15 24]
[1 2 3]
[3 6 9]

В массивах можно брать срез. Для одномерных массивов эта операция аналогична стандартному срезу в Python. Для многомерного массива можно задавать диапазон среза отдельно для каждой оси. Таким образом, можно взять срез отдельной части матрицы, указав, какие строки и столбцы должны попасть в срез:

import numpy as np

a = np.arange(1, 13).reshape(3, 4)
print(a)
print()
print(a[:2, 2:])
print()
print(a[:, ::2])

Вывод программы:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

[[3 4]
 [7 8]]

[[ 1  3]
 [ 5  7]
 [ 9 11]]

В цикле for можно пройти по элементам первой оси массива:

import numpy as np

a = np.arange(1, 13).reshape(3, 4)
print(a)
for row in a:
    print(row)

Вывод программы:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

[1 2 3 4]
[5 6 7 8]
[ 9 10 11 12]

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

import numpy as np

a = np.arange(1, 13).reshape(3, 4)
print(a)
print()
print("; ".join(str(el) for el in a.flat))

Вывод программы:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12

Покажем на примере различие в скорости работы массивов и списков. Посчитаем сумму квадратных корней первых 107 чисел.

import numpy as np
from time import time

t = time()
print(f"Результат итератора: {sum(x ** 0.5 for x in range(10 ** 7))}.")
print(f"{time() - t} с.")
t = time()
print(f"Результат numpy: {np.sqrt(np.arange(10 ** 7)).sum()}.")
print(f"{time() - t} с.")

Вывод программы:

Результат итератора: 21081849486.439312.
1.7823209762573242 с.
Результат numpy: 21081849486.442448.
0.05197310447692871 с.

Библиотека numpy решила задачу в 30 раз быстрее, чем итератор.

За счёт скорости работы и удобной обработки массивов библиотека numpy используется для расчётов во многих других библиотеках. С одной из них мы поработаем в следующей главе.

Ещё по теме

Для более детального изучения библиотеки numpy рекомендуем почитать документацию.

Понравилась статья? Поделить с друзьями:
  • Как найти ломаную линию миллиметрах
  • Хованское кладбище официальный сайт как найти могилу
  • Browser exe что это за процесс windows 7 как исправить
  • Ошибка 404 на смарт тв как исправить
  • Где павелецкая вокзал как найти