专栏首页数据科学CLUBNumpy中的通用函数

Numpy中的通用函数

NumPy数组的计算:通用函数缓慢的循环通用函数介绍探索Numpy的通用函数高级通用函数的特性聚合:最小值、 最大值和其他值数组值求和最大值和最小值其他聚合函数

《Python数据科学手册》读书笔记

NumPy数组的计算:通用函数

NumPy 数组的计算有时非常快, 有时也非常慢。使 NumPy 变快的关键是利用向量化操作, 通常在 NumPy 的通用函数(ufunc) 中实现。

缓慢的循环

python的缓慢通常出现在许多小操作与要不断重复的时候,比如对数组每个元素做循环

# 计算数组每个元素的倒数
import numpy as np
np.random.seed()

def compute_reciprocals(values):
    output = np.empty(len(values))
    for i in range(len(values)):
        output[i] = 1.0 / values[i]
    return output

values = np.random.randint(, , size=)
compute_reciprocals(values)
array([0.16666667, 1.        , 0.25      , 0.25      , 0.125     ])
big_array = np.random.randint(, , size=)
# 循环一百万次所要的时间
%timeit compute_reciprocals(big_array)
5.73 s ±  ms per loop (mean ± std. dev. of  runs,  loop each)

通用函数介绍

Numpy 为很多类型的操作提供了非常方便的,静态类型的可编译程序的接口,也被称作向量操作,是通过通用函数实现的,这样会取得更快的执行效率

# 输出结果相同
print(compute_reciprocals(values))
print(1.0 / values)
[0.16666667 1.         0.25       0.25       0.125     ]
[0.16666667 1.         0.25       0.25       0.125     ]
# 当数组很大时,通用函数的优势也就展现出来了
%timeit (1.0 / big_array)
12.1 ms ± 2.04 ms per loop (mean ± std. dev. of  runs,  loops each)
# 两个数组进行运算
np.arange() / np.arange(, )
array([0.        , 0.5       , 0.66666667, 0.75      , 0.8       ])
# 多维数组进行运算
x = np.arange().reshape((, ))
 ** x
array([[  1,   2,   4],
       [  8,  16,  32],
       [ 64, 128, 256]], dtype=int32)

探索Numpy的通用函数

  • 一元通用函数
  • 二元通用函数
  1. 数组的运算
x = np.arange()
print("x     =", x)
print("x + 5 =", x + )
print("x - 5 =", x - )
print("x * 2 =", x * )
print("x / 2 =", x / )
print("x // 2 =", x // )  # 地板除
print("-x     = ", -x)
print("x ** 2 = ", x ** )
print("x % 2  = ", x % )
x     = [0 1 2 3]
x + 5 = [5 6 7 8]
x - 5 = [-5 -4 -3 -2]
x * 2 = [0 2 4 6]
x / 2 = [0.  0.5 1.  1.5]
x // 2 = [0 0 1 1]
-x     =  [ 0 -1 -2 -3]
x ** 2 =  [0 1 4 9]
x % 2  =  [0 1 0 1]

Nmupy实现的算数运算符

Operator

Equivalent ufunc

Description

+

np.add

Addition (e.g., 1 + 1 = 2)

-

np.subtract

Subtraction (e.g., 3 - 2 = 1)

-

np.negative

Unary negation (e.g., -2)

*

np.multiply

Multiplication (e.g., 2 * 3 = 6)

/

np.divide

Division (e.g., 3 / 2 = 1.5)

//

np.floor_divide

Floor division (e.g., 3 // 2 = 1)

**

np.power

Exponentiation (e.g., 2 ** 3 = 8)

%

np.mod

Modulus/remainder (e.g., 9 % 4 = 1

-(0.5*x + ) ** 
array([-1.  , -2.25, -4.  , -6.25])
np.add(x, )
array([, , , ])
  1. 绝对值
x = np.array([-2, -1, , , ])
abs(x)
array([, , , , ])
np.absolute(x)#同np.abs
array([, , , , ])
x = np.array([ - 4j,  - 3j,  + 0j,  + 1j])
np.abs(x)
array([5., 5., 2., 1.])
  1. 三角函数
theta = np.linspace(, np.pi, )
print("theta      = ", theta)
print("sin(theta) = ", np.sin(theta))
print("cos(theta) = ", np.cos(theta))
print("tan(theta) = ", np.tan(theta))
theta      =  [0.         1.57079633 3.14159265]
sin(theta) =  [0.0000000e+00 1.0000000e+00 1.2246468e-16]
cos(theta) =  [ 1.000000e+00  6.123234e-17 -1.000000e+00]
tan(theta) =  [ 0.00000000e+00  1.63312394e+16 -1.22464680e-16]
x = [-1, , ]
print("x         = ", x)
print("arcsin(x) = ", np.arcsin(x))
print("arccos(x) = ", np.arccos(x))
print("arctan(x) = ", np.arctan(x))
x         =  [-1, 0, 1]
arcsin(x) =  [-1.57079633  0.          1.57079633]
arccos(x) =  [3.14159265 1.57079633 0.        ]
arctan(x) =  [-0.78539816  0.          0.78539816]
  1. 指数和对数
x = [, , ]
print("x     =", x)
print("e^x   =", np.exp(x))
print("2^x   =", np.exp2(x))
print("3^x   =", np.power(, x))
x     = [1, 2, 3]
e^x   = [ 2.71828183  7.3890561  20.08553692]
^x   = [2. 4. 8.]
^x   = [ 3  9 27]
x = [, , , ]
print("x        =", x)
print("ln(x)    =", np.log(x))
print("log2(x)  =", np.log2(x))
print("log10(x) =", np.log10(x))
x        = [1, 2, 4, 10]
ln(x)    = [0.         0.69314718 1.38629436 2.30258509]
log2(x)  = [0.         1.         2.         3.32192809]
log10(x) = [0.         0.30103    0.60205999 1.        ]
x = [, 0.001, 0.01, 0.1]
print("exp(x) - 1 =", np.expm1(x))
print("log(1 + x) =", np.log1p(x))
exp(x) - 1 = [0.         0.0010005  0.01005017 0.10517092]
log(1 + x) = [0.         0.0009995  0.00995033 0.09531018]
  1. 专门的通用函数

除了以上介绍到的, NumPy 还提供了很多通用函数, 包括双曲三角函数、 比特位运算、 比较运算符、 弧度转化为角度的运算、 取整 和求余运算, 等等。浏览 NumPy 的文档将会揭示很多有趣的功能。

from scipy import special
# Gamma函数和相关函数
x = [, , ]
print("gamma(x)     =", special.gamma(x))
print("ln|gamma(x)| =", special.gammaln(x))
print("beta(x, 2)   =", special.beta(x, ))
gamma(x)     = [1.0000e+00 2.4000e+01 3.6288e+05]
ln|gamma(x)| = [ 0.          3.17805383 12.80182748]
beta(x, 2)   = [0.5        0.03333333 0.00909091]
# 误差函数(高斯函数)
# 它的实现和它的逆实现
x = np.array([, 0.3, 0.7, 1.0])
print("erf(x)  =", special.erf(x))
print("erfc(x) =", special.erfc(x))
print("erfinv(x) =", special.erfinv(x))
erf(x)  = [0.         0.32862676 0.67780119 0.84270079]
erfc(x) = [1.         0.67137324 0.32219881 0.15729921]
erfinv(x) = [0.         0.27246271 0.73286908        inf]

高级通用函数的特性

  1. 指定输入

在进行大量运算时, 有时候指定一个用于存放运算结果的数组是非常有用的。不同于创建临时数组, 你可以用这个特性将计算结果直接写入到你期望的存储位置。所有的通用函数都可以通过 out 参数来指定计算结果的存放位置:

x = np.arange()
y = np.empty()
np.multiply(x, , out=y)
print(y)
[ 0. 10. 20. 30. 40.]
y = np.zeros()
np.power(, x, out=y[::])
print(y)
[ 1.  0.  2.  0.  4.  0.  8.  0. 16.  0.]

如果这里写的是 y[::2] = 2 ** x, 那么结果将是创建一个临时数组, 该数组存放的是 2 ** x 的结果, 并且接下来会将这些值复制到 y 数组中。 对于上述例子中比较小的计算量来说, 这两种方式的差别并不大。但是对于较大的数组, 通过慎重使用 out 参数将能够有效节约内存。

  1. 聚合

二元通用函数有些非常有趣的聚合功能, 这些聚合可以直接在对象上计算。例如, 如果我们希望用一个特定的运算 reduce 一个数组, 那么可以用任何通用函数的 reduce 方法。一个 reduce 方法会对给定的元素和操作重复执行, 直至得到单个的结果。

x = np.arange(, )
# 返回数组中所有元素的和
np.add.reduce(x)
15
# 返回数组中所有元素的乘积
np.multiply.reduce(x)
120
# 存储每次计算的中间结果
np.add.accumulate(x)
array([ ,  ,  , , ], dtype=int32)
np.multiply.accumulate(x)
array([  ,   ,   ,  , ], dtype=int32)

请注意, 在一些特殊情况中, NumPy 提供了专用的函数(np.sum、 np.prod、 np.cumsum、 np.cumprod ) , 它们也可以实现以上 reduce 的功能。

  1. 外积

最后, 任何通用函数都可以用 outer 方法获得两个不同输入数组所有元素对的函数运算结果。这意味着你可以用一行代码实现一个乘法表:

np.multiply.outer([, , ], [, , ])
array([[ 4,  5,  6],
       [ 8, 10, 12],
       [12, 15, 18]])
A = np.array([[, , ], 
              [, , ]])
B = np.array([[, , , ]])
C = np.multiply.outer(A, B)
C
array([[[[ 1,  2,  3,  4]],

        [[ 2,  4,  6,  8]],

        [[ 3,  6,  9, 12]]],


       [[[ 4,  8, 12, 16]],

        [[ 5, 10, 15, 20]],

        [[ 6, 12, 18, 24]]]])

通用函数:更多的信息有关通用函数的更多信息(包括可用的通用函数的完整列表) 可以在 NumPy(http://www.numpy.org)和 SciPy(http://www.scipy.org) 文档的网站找到。

聚合:最小值、 最大值和其他值

当你面对大量的数据时, 第一个步骤通常都是计算相关数据的概括统计值。最常用的概括统计值可能是均值和标准差, 这两个值能让你分别概括出数据集中的“经典”值, 但是其他一些形式的聚合也是非常有用的(如求和、 乘积、 中位数、 最小值和最大值、 分位数, 等等) 。

数组值求和

L = np.random.random()
sum(L)
46.18308216715081
# 结果是一样的
np.sum(L)
46.183082167150815
# NumPy的版本运行的更快些
big_array = np.random.rand()
%timeit sum(big_array)
%timeit np.sum(big_array)
 ms ± 42.4 ms per loop (mean ± std. dev. of  runs,  loops each)
4.73 ms ±  µs per loop (mean ± std. dev. of  runs,  loops each)

最大值和最小值

min(big_array), max(big_array)
(7.071203171893359e-07, 0.9999997207656334)
np.min(big_array), np.max(big_array)
(7.071203171893359e-07, 0.9999997207656334)
%timeit min(big_array)
%timeit np.min(big_array)
 ms ±  µs per loop (mean ± std. dev. of  runs,  loops each)
 µs ± 6.87 µs per loop (mean ± std. dev. of  runs,  loops each)

对于 min、 max、 sum 和其他 NumPy 聚合, 一种更简洁的语法形式是数组对象直接调用这些方法:

print(big_array.min(), big_array.max(), big_array.sum())
7.071203171893359e-07 0.9999997207656334 500216.8034810001
  1. 多维度聚合

一种常用的聚合操作是沿着一行或一列聚合。例如, 假设你有一些数据存储在二维数组中:

M = np.random.random((, ))
print(M)
[[0.79832448 0.44923861 0.95274259 0.03193135]
 [0.18441813 0.71417358 0.76371195 0.11957117]
 [0.37578601 0.11936151 0.37497044 0.22944653]]

默认情况下, 每一个 NumPy 聚合函数将会返回对整个数组的聚合结果:

M.sum()
5.1136763453287335
# 找到每一列的最小值
M.min(axis=)
array([0.18441813, 0.11936151, 0.37497044, 0.03193135])
# 找到每一行的最大值
M.max(axis=)
array([0.95274259, 0.76371195, 0.37578601])

其他聚合函数

Function Name

NaN-safe Version

Description

np.sum

np.nansum

Compute sum of elements

np.prod

np.nanprod

Compute product of elements

np.mean

np.nanmean

Compute mean of elements

np.std

np.nanstd

Compute standard deviation

np.var

np.nanvar

Compute variance

np.min

np.nanmin

Find minimum value

np.max

np.nanmax

Find maximum value

np.argmin

np.nanargmin

Find index of minimum value

np.argmax

np.nanargmax

Find index of maximum value

np.median

np.nanmedian

Compute median of elements

np.percentile

np.nanpercentile

Compute rank-based statistics of elements

np.any

N/A

Evaluate whether any elements are true

np.all

N/A

Evaluate whether all elements are true

本文分享自微信公众号 - 数据科学CLUB(jiji8215),作者:少年吉

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Scipy使用简介

    Scipy中的special模块是一个非常完整的函数库,其中包含了基本数学函数,特殊数学函数以及numpy中所出现的所有函数。伽马函数是概率统计学中经常出现的一...

    用户3577892
  • Numpy的广播功能

    数组的计算:广播广播的介绍广播的规则广播的实际应用比较,掩码和布尔逻辑比较操作操作布尔数组将布尔数组作为掩码

    用户3577892
  • Numpy初探

    理解Python中的数据类型Python代码Python代码Python整型不仅仅是一个整型Python列表不仅仅是一个列表Python中的固定类型数组从Pyt...

    用户3577892
  • Numpy实战全集

    0.导语1.Numpy基本操作1.1 列表转为矩阵1.2 维度1.3 行数和列数()1.4 元素个数2.Numpy创建array2.1 一维array创建2.1...

    公众号guangcity
  • Numpy核心语法和代码整理汇总!

    NumPy(Numeric Python)提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。多为很多大型...

    公众号机器学习与生成对抗网络
  • Python之numpy的ndarray数组使用方法介绍

    NumPy的全名为Numeric Python,是一个开源的Python科学计算库,它包括:

    我是攻城师
  • python中numpy和pandas介

    numpy和pandas是python中用于处理数据的两个库。 numpy介绍: numpy用于处理array,且array中数据类型必须一致。下面以代码备注的...

    py3study
  • Python之Numpy初识

    今天翻了下计划,要学习Numpy了,所以得调动脑细胞的积极性,看看能有什么收获。 首先得了解下什么是Numpy,从我的印象中,一般提到这个工具都会和机器学习关...

    jeanron100
  • 数据分析 ———— numpy基础(一)

    准备了好长时间,想要写点关于数据分析的文章,但一直忙于工作,忙里抽闲更新一篇关于numpy的文章。

    andrew_a
  • 【玩转腾讯云】深度学习之《深度学习入门》学习笔记(一)Python入门

    最近学习吴恩达《Machine Learning》课程以及《深度学习入门:基于Python的理论与实现》书,一些东西总结了下。现就后者学习进行笔记总结。本文是本...

    ZNing

扫码关注云+社区

领取腾讯云代金券