前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Numpy中的通用函数

Numpy中的通用函数

作者头像
用户3577892
发布2020-06-12 16:32:38
1.8K0
发布2020-06-12 16:32:38
举报
文章被收录于专栏:数据科学CLUB数据科学CLUB

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

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

NumPy数组的计算:通用函数

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

缓慢的循环

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

代码语言:javascript
复制
# 计算数组每个元素的倒数
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)
代码语言:javascript
复制
array([0.16666667, 1.        , 0.25      , 0.25      , 0.125     ])
代码语言:javascript
复制
big_array = np.random.randint(, , size=)
# 循环一百万次所要的时间
%timeit compute_reciprocals(big_array)
代码语言:javascript
复制
5.73 s ±  ms per loop (mean ± std. dev. of  runs,  loop each)

通用函数介绍

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

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

探索Numpy的通用函数

  • 一元通用函数
  • 二元通用函数
  1. 数组的运算
代码语言:javascript
复制
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 % )
代码语言:javascript
复制
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

代码语言:javascript
复制
-(0.5*x + ) ** 
代码语言:javascript
复制
array([-1.  , -2.25, -4.  , -6.25])
代码语言:javascript
复制
np.add(x, )
代码语言:javascript
复制
array([, , , ])
  1. 绝对值
代码语言:javascript
复制
x = np.array([-2, -1, , , ])
abs(x)
代码语言:javascript
复制
array([, , , , ])
代码语言:javascript
复制
np.absolute(x)#同np.abs
代码语言:javascript
复制
array([, , , , ])
代码语言:javascript
复制
x = np.array([ - 4j,  - 3j,  + 0j,  + 1j])
np.abs(x)
代码语言:javascript
复制
array([5., 5., 2., 1.])
  1. 三角函数
代码语言:javascript
复制
theta = np.linspace(, np.pi, )
代码语言:javascript
复制
print("theta      = ", theta)
print("sin(theta) = ", np.sin(theta))
print("cos(theta) = ", np.cos(theta))
print("tan(theta) = ", np.tan(theta))
代码语言:javascript
复制
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]
代码语言:javascript
复制
x = [-1, , ]
print("x         = ", x)
print("arcsin(x) = ", np.arcsin(x))
print("arccos(x) = ", np.arccos(x))
print("arctan(x) = ", np.arctan(x))
代码语言:javascript
复制
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. 指数和对数
代码语言:javascript
复制
x = [, , ]
print("x     =", x)
print("e^x   =", np.exp(x))
print("2^x   =", np.exp2(x))
print("3^x   =", np.power(, x))
代码语言:javascript
复制
x     = [1, 2, 3]
e^x   = [ 2.71828183  7.3890561  20.08553692]
^x   = [2. 4. 8.]
^x   = [ 3  9 27]
代码语言:javascript
复制
x = [, , , ]
print("x        =", x)
print("ln(x)    =", np.log(x))
print("log2(x)  =", np.log2(x))
print("log10(x) =", np.log10(x))
代码语言:javascript
复制
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.        ]
代码语言:javascript
复制
x = [, 0.001, 0.01, 0.1]
print("exp(x) - 1 =", np.expm1(x))
print("log(1 + x) =", np.log1p(x))
代码语言:javascript
复制
exp(x) - 1 = [0.         0.0010005  0.01005017 0.10517092]
log(1 + x) = [0.         0.0009995  0.00995033 0.09531018]
  1. 专门的通用函数

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

代码语言:javascript
复制
from scipy import special
代码语言:javascript
复制
# Gamma函数和相关函数
x = [, , ]
print("gamma(x)     =", special.gamma(x))
print("ln|gamma(x)| =", special.gammaln(x))
print("beta(x, 2)   =", special.beta(x, ))
代码语言:javascript
复制
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]
代码语言:javascript
复制
# 误差函数(高斯函数)
# 它的实现和它的逆实现
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))
代码语言:javascript
复制
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 参数来指定计算结果的存放位置:

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

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

  1. 聚合

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

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

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

  1. 外积

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

代码语言:javascript
复制
np.multiply.outer([, , ], [, , ])
代码语言:javascript
复制
array([[ 4,  5,  6],
       [ 8, 10, 12],
       [12, 15, 18]])
代码语言:javascript
复制
A = np.array([[, , ], 
              [, , ]])
B = np.array([[, , , ]])
代码语言:javascript
复制
C = np.multiply.outer(A, B)
C
代码语言:javascript
复制
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) 文档的网站找到。

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

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

数组值求和

代码语言:javascript
复制
L = np.random.random()
sum(L)
代码语言:javascript
复制
46.18308216715081
代码语言:javascript
复制
# 结果是一样的
np.sum(L)
代码语言:javascript
复制
46.183082167150815
代码语言:javascript
复制
# NumPy的版本运行的更快些
big_array = np.random.rand()
%timeit sum(big_array)
%timeit np.sum(big_array)
代码语言:javascript
复制
 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)

最大值和最小值

代码语言:javascript
复制
min(big_array), max(big_array)
代码语言:javascript
复制
(7.071203171893359e-07, 0.9999997207656334)
代码语言:javascript
复制
np.min(big_array), np.max(big_array)
代码语言:javascript
复制
(7.071203171893359e-07, 0.9999997207656334)
代码语言:javascript
复制
%timeit min(big_array)
%timeit np.min(big_array)
代码语言:javascript
复制
 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 聚合, 一种更简洁的语法形式是数组对象直接调用这些方法:

代码语言:javascript
复制
print(big_array.min(), big_array.max(), big_array.sum())
代码语言:javascript
复制
7.071203171893359e-07 0.9999997207656334 500216.8034810001
  1. 多维度聚合

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

代码语言:javascript
复制
M = np.random.random((, ))
print(M)
代码语言:javascript
复制
[[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 聚合函数将会返回对整个数组的聚合结果:

代码语言:javascript
复制
M.sum()
代码语言:javascript
复制
5.1136763453287335
代码语言:javascript
复制
# 找到每一列的最小值
M.min(axis=)
代码语言:javascript
复制
array([0.18441813, 0.11936151, 0.37497044, 0.03193135])
代码语言:javascript
复制
# 找到每一行的最大值
M.max(axis=)
代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据科学CLUB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • NumPy数组的计算:通用函数
    • 缓慢的循环
      • 通用函数介绍
        • 探索Numpy的通用函数
          • 高级通用函数的特性
          • 聚合:最小值、 最大值和其他值
            • 数组值求和
              • 最大值和最小值
                • 其他聚合函数
            相关产品与服务
            数据保险箱
            数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档