English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
NumPy 提供了两种基本的对象,即 ndarray 和 ufunc 对象。ufunc 是 universal function的缩写,意思是“通用函数”,它是一种能对数组的每个元素进行操作的函数。
许多 ufunc 函数都是用C语言级别实现的,因此它们的计算速度非常快。
此外,ufun 比 math 模块中的函数更灵活。math 模块的输入一般是标量,但 NumPy 中的函数可以是向量或矩阵,而利用向量或矩阵可以避免使用循环语句,这点在机器学习、深度学习中非常重要。
ufunc 用于在 NumPy 中实现矢量化,这比迭代元素要快得多。
它们还提供广播和其他方法,例如减少、累加等,它们对计算非常有帮助。
ufuncs 还接受其他参数,比如:
where 布尔值数组或条件,用于定义应在何处进行操作。
dtype 定义元素的返回类型。
out 返回值应被复制到的输出数组。
函数 | 使用方法 |
sqrt() | 计算序列化数据的平方根 |
sin()、cos() | 三角函数 |
abs() | 计算序列化数据的绝对值 |
dot() | 矩阵运算 |
log()、logl()、log2() | 对数函数 |
exp() | 指数函数 |
cumsum()、cumproduct() | 累计求和、求积 |
sum() | Суммирование последовательности данных |
mean() | Вычисление среднего |
median() | Вычисление медианы |
std() | Вычисление стандартного отклонения |
var() | Вычисление дисперсии |
corrcoef() | Вычисление корреляционного коэффициента |
import time import math import numpy as np x = [i * 0.001 for i in np.arange(1000000)] start = time.clock() for i, t in enumerate(x): x[i] = math.sin(t) print("math.sin:", time.clock() - start) x = [i * 0.001 for i in np.arange(1000000)] x = np.array(x) start = time.clock() np.sin(x) print("numpy.sin:", time.clock() - start)
Результат выполнения:
math.sin: 0.5169950000000005 numpy.sin: 0.05381199999999886
Таким образом, numpy.sin в 10 раз быстрее math.sin.
Преобразование инструкций итерации в векторные операции называется векторизацией.
Благодаря оптимизации современных CPU для таких операций, они выполняются быстрее.
Сложение элементов двух списков:
Список 1: [1, 2, 3, 4]
Список 2: [4, 5, 6, 7]
Одним из методов является итерация по двум спискам и сложение каждого элемента.
Если нет ufunc, мы можем использовать встроенный метод zip() в Python:
x = [1, 2, 3, 4] y = [4, 5, 6, 7] z = [] for i, j in zip(x, y): z.append(i + j) print(z)
Результат выполнения:
[5, 7, 9, 11]
Для этого у NumPy есть ufunc, называемая add(x, y), которая выдает одинаковый результат, и с помощью ufunc мы можем использовать функцию add():
import numpy as np x = [1, 2, 3, 4] y = [4, 5, 6, 7] z = np.add(x, y) print(z)
Результат выполнения:
[5, 7, 9, 11]
Полное использование встроенных функций библиотеки NumPy для реализации векторизации вычислений может значительно повысить производительность выполнения. Внутренние функции библиотеки NumPy используют SIMD инструкции. Векторизация, как показано ниже, значительно быстрее, чем вычисления с использованием циклов. Если использовать GPU, производительность будет еще выше, но NumPy не поддерживает GPU.
Смотрите следующий код:
import time import numpy as np x1 = np.random.rand(1000000) x2 = np.random.rand(1000000) ## Вычисление точного произведения векторами с помощью цикла tic = time.process_time() dot = 0 for i in range(len(x1)): dot += x1[i]*x2[i] toc = time.process_time() print("dot = " + str(dot) + "\nfor-цикл ---- Время расчета = " + str(1000*(toc - tic)) + "ms") ## Использование функции np.dot для вычисления точного произведения tic = time.process_time() dot = 0 dot = np.dot(x1,x2) toc = time.process_time() print("dot = " + str(dot) + "\nВерсия Verctor ---- Время расчета = " + str(1000*(toc - tic)) + "ms")
Результат выполнения:
dot = 250215.601995 for-цикл ---- Время расчета = 798.3389819999998ms dot = 250215.601995 Версия Verctor ---- Время расчета = 1.885051999999554ms