Skip to content

NumPy 扩展

1、python 导论

Numpy 是Python社区最重要的支持包之一,是处理多维数组的数值运算库,可以用于机器学习,图像处理、语言处理、数值计算等各种不同应用场景。虽然Numpy尚未成为python本身基础库。但已经成为Python多维数据处理的实质性标准。

Numpy目前由Numpy团队负责开发与维护,该项目成立于2005年。

Numpy版本目前更新状况可以通过下面的命令进行查询。

import numpy
numpy.__version__
'1.26.4'

1.1 内置文档

使用Tab键可以在Ipython或者Jupyter Notebook中查看自动补全和各种函数的帮助文档。对于Numpy也是如此。显示Numpy命名空间中的内容,可以使用如下方法:

In [3]: np.<TAB>
如果显示Numpy中的内置文档,可以直接使用下面方法:

In [4]: np?

1.2 内置数据类型

我们需要花点时间去区分Numpy和Python的数据类型差异

2、创建数组

import numpy as np
# 使用np.array()创建数组:
np.array([1, 4, 2, 5, 3])
array([1, 4, 2, 5, 3])
np.array([1, 4, 2, 5, 3]).dtype
dtype('int32')

Numpy 会根据输入的内容,默认ndarray的格式和数据类型

np.array([3.14, 4, 2, 3]).dtype
dtype('float64')

可以使用dtype关键字明确指定数据类型

np.array([1, 2, 3, 4], dtype='float32')
array([1., 2., 3., 4.], dtype=float32)

与Python不同,Numpy可以指定多维数组,下面是建立多维数组的示例。

# nested lists result in multi-dimensional arrays
np.array([range(i, i + 3) for i in [2, 4, 6]])

array([[2, 3, 4],
       [4, 5, 6],
       [6, 7, 8]])

2.1 简单的数据创建方法

# Create a length-10 integer array filled with zeros
np.zeros(10, dtype=int)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
# Create a 3x5 floating-point array filled with ones
np.ones((3, 5), dtype=float)
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
# Create a 3x5 array filled with 3.14
np.full((3, 5), 3.14)
array([[3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14]])
# 创建线性序列
# 从 0开始, 到 20结束, 步长 2
# (与内置的 range() 函数类似)
np.arange(0, 20, 2)
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
# 从0到1之间创建等距的5个元素组成的数组
np.linspace(0, 1, 5)
array([0.  , 0.25, 0.5 , 0.75, 1.  ])
# 创建一个 3x3 正态分布的数组
# 随机数位于 0 和 1 之间
np.random.random((3, 3))
array([[0.39970806, 0.46597739, 0.0257459 ],
       [0.05933404, 0.614792  , 0.5910225 ],
       [0.76213103, 0.89892807, 0.43980076]])
# 创建 3x3 标准正态分布数组
np.random.normal(0, 1, (3, 3))
array([[-0.37362824,  2.17639874, -0.69186425],
       [ 0.42087952,  0.01164588,  0.60949926],
       [-0.02950002,  0.18922248, -1.04251865]])
# 创建 3x3 整数随机数组,整数区间为 [0, 10)
np.random.randint(0, 10, (3, 3))
array([[4, 3, 8],
       [3, 8, 4],
       [6, 4, 0]])
# 创建 3x3 单位矩阵
np.eye(3)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
# Create an uninitialized array of three integers
# The values will be whatever happens to already exist at that memory location
np.empty((3,3))
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

2.2 Numpy 的标准数据类型

标准的Numpy标准数据类型如下面表中所示。请注意,当构建一个数组时,你可以用一个字符串参数来指定数据类型,如:

np.zeros(10, dtype='int16')
也可以用一个Numpy对象来指定数据类型:
np.zeros(10, dtype=np.int16)

数据类型 描述
bool_ 布尔型 (True or False) 一个字节存储
int_ 默认整型 (same as C long; normally either int64 or int32)
intc 与 C 语言中int 相同(normally int32 or int64)
intp 用作索引的整型 (与C语言中 ssize_t相同; 通常是int32 或者 int64)
int8 字节 (-128 to 127)
int16 整型 (-32768 to 32767)
int32 整型 (-2147483648 to 2147483647)
int64 整型 (-9223372036854775808 to 9223372036854775807)
uint8 无符号整型 (0 to 255)
uint16 无符号整型 (0 to 65535)
uint32 无符号整型 (0 to 4294967295)
uint64 无符号整型 (0 to 18446744073709551615)
float_ float64简化形式.
float16 半精度浮点型: sign bit, 5 bits exponent, 10 bits mantissa
float32 单精度浮点型 float: sign bit, 8 bits exponent, 23 bits mantissa
float64 双精度浮点型: sign bit, 11 bits exponent, 52 bits mantissa
complex_ 简写复数 complex128.
complex64 复数, 2个32位浮点型
complex128 复数,2个64位浮点型

3、数组基础

3.1 Numpy数组属性

import numpy as np
np.random.seed(0)  # seed for reproducibility

x1 = np.random.randint(10, size=6)  # One-dimensional array
x2 = np.random.randint(10, size=(3, 4))  # Two-dimensional array
x3 = np.random.randint(10, size=(3, 4, 5))  # Three-dimensional array

每个数组都有ndim(数组维度)、shape(数组每个维度大小)、size(数组总大小)属性

print("x3 ndim: ", x3.ndim)
print("x3 shape:", x3.shape)
print("x3 size: ", x3.size)
x3 ndim:  3
x3 shape: (3, 4, 5)
x3 size:  60

另一个有用的属性是dtype,显示数组的数据类型,之前在标准类型中有介绍。

print("dtype:", x3.dtype)
dtype: int32

其他属性包括数组元素大小的itemsize ,以及表示总数组字节大小的属性nbytes

print("itemsize:", x3.itemsize, "bytes")
print("nbytes:", x3.nbytes, "bytes")
itemsize: 4 bytes
nbytes: 240 bytes

3.2数组索引:获取单个元素

x1
array([5, 0, 3, 3, 7, 9])
x1[0]
5
x1[4]
7

为了获取数组末尾索引,可以用负值做索引

x1[-1]

9
x1[-2]
7

在多维数组中,可以用逗号分隔的索引元组获得元素:

x2

array([[3, 5, 2, 4],
       [7, 6, 8, 8],
       [1, 6, 7, 7]])
x2[0, 0]
3
x2[2, 0]
1
x2[2, -1]
7

可以用上面的索引方式直接修改元素

x2[0, 0] = 12
x2
array([[12, 5, 2, 4], [ 7, 6, 8, 8], [ 1, 6, 7, 7]])

请注意,和Python不同,Numpy数组是固定类型的,这就意味着当你试图将一个浮点型值插入整数型数组时,浮点型将被截短成为整型,且该过程自动完成,没有提示和警告。

x1[0] = 3.14159  # 将会被截断
x1

array([3, 0, 3, 3, 7, 9])

3.3 数组切片:获取子数组

切片的方法与Python中类似,使用冒号(:)来完成。基本格式是:

x[start:stop:step]

如果以上三个参数都没有指定,默认start=0 ,stop=维度大小,step=1

x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x[:5]  # first five elements
array([0, 1, 2, 3, 4])
x[5:]  # elements after index 5
array([5, 6, 7, 8, 9])
x[4:7]  # middle sub-array
array([4, 5, 6])
x[::2]  # every other element
array([0, 2, 4, 6, 8])
x[1::2]  # every other element, starting at index 1
array([1, 3, 5, 7, 9])

一种常见的逆转数组的方法如下:

x[::-1]  # 所有元素逆序
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
x[5::-2]  # 从 5开始每隔一个元素逆序表示
array([5, 3, 1])

多维子数组

多维切片也采用同样方法处理,用冒号(:)分割。如示例:

x2
array([[12,  5,  2,  4],
       [ 7,  6,  8,  8],
       [ 1,  6,  7,  7]])
x2[:2, :3]  # 两行,三列
array([[12,  5,  2],
       [ 7,  6,  8]])
x2[:3, ::2]  # 所有行,每隔一列
array([[12,  2],
       [ 7,  8],
       [ 1,  7]])

子数组维度也可以同时被逆序:

x2[::-1, ::-1]
array([[ 7,  7,  6,  1],
       [ 8,  8,  6,  7],
       [ 4,  2,  5, 12]])

获取数组的行和列

一种常见的处理是获取数组的单行和单列,可以将索引和切片结合起来:

print(x2[:, 0])  #  x2第一列
[12  7  1]
print(x2[0, :])  #  x2第一行
[12  5  2  4]

获取行时,出于语法简洁,可以省略空的切片:

print(x2[0])  # 相当于 x2[0, :]
[12  5  2  4]

非副本视图的子序列

数组切片的一个特征是返回的是数组数据的视图,不是数值数据的副本,这样在视图上修改,整个数据也进行了修改。这一点是Numpy数组切片与Python列表切片的不同。

print(x2)
[[12  5  2  4]
 [ 7  6  8  8]
 [ 1  6  7  7]]
x2_sub = x2[:2, :2]
print(x2_sub)
[[12  5]
 [ 7  6]]

如果我们修改这个子数组,原始数据也被修改了。

x2_sub[0, 0] = 99
print(x2_sub)
[[99  5]
 [ 7  6]]
print(x2)
[[99  5  2  4]
 [ 7  6  8  8]
 [ 1  6  7  7]]

Numpy 的这种特性很有用:意味着在处理非常大的数据集时,可以获取这些数据集的片段,不用复制底层的数据缓存。

创建数组的副本

如果我们需要使用副本方式,则可以使用COPY()方法予以解决:

x2_sub_copy = x2[:2, :2].copy()
print(x2_sub_copy)
[[99  5]
 [ 7  6]]
x2_sub_copy[0, 0] = 42
print(x2_sub_copy)
[[42  5]
 [ 7  6]]
print(x2)
[[99  5  2  4]
 [ 7  6  8  8]
 [ 1  6  7  7]]

3.4 数组的变形

使用reshape()函数,可以改变数组的形状。

grid = np.arange(1, 10).reshape((3, 3))
print(grid)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

该方法的前提是,原始数组的大小必须与变形的数组大小一致。如果满足该条件,reshape何以得到原数组的一个非副本视图。

另一个常见的变形模式:将一个一维数组变为二维数组的行或者列的矩阵。可以使用reshape()方法,也可以在一个简单切片操作中利用newaxis关键字。

x = np.array([1, 2, 3])

#得到行向量
x.reshape((1, 3))
array([[1, 2, 3]])
# 通过newaxis 获得行向量
x[np.newaxis, :]
array([[1, 2, 3]])
# 通过reshape获得列向量
x.reshape((3, 1))
array([[1],
       [2],
       [3]])

3.5数组的拼接和分割

当数组需要合并和分割,需要使用相应的函数进行操作。

数组的拼接

拼接使用函数有:np.concatenate, np.vstack, and np.hstack

x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
np.concatenate([x, y])
array([1, 2, 3, 3, 2, 1])

也可以一次拼接多个数组

z = [99, 99, 99]
print(np.concatenate([x, y, z]))
[ 1  2  3  3  2  1 99 99 99]

对于二维数组,方法依然有效:

grid = np.array([[1, 2, 3],
                 [4, 5, 6]])
#沿着竖轴排列
np.concatenate([grid, grid])
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
# 沿着第二个轴(横轴)进行拼接
np.concatenate([grid, grid], axis=1)
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])

当矩阵维度固定时,可以使用np.vstack (垂直方向) and np.hstack (水平方向) 进行拼接。

x = np.array([1, 2, 3])
grid = np.array([[9, 8, 7],
                 [6, 5, 4]])

# 垂直栈拼接
np.vstack([x, grid])
array([[1, 2, 3],
       [9, 8, 7],
       [6, 5, 4]])
# 水平栈拼接
y = np.array([[99],
              [99]])
np.hstack([grid, y])
array([[ 9,  8,  7, 99],
       [ 6,  5,  4, 99]])

数组的分割

数组分割与数组的拼接相反。使用的函数为: np.split, np.hsplit, 和 np.vsplit,在函数中传递一个索引列表作为参数,记录分裂点位置:

x = [1, 2, 3, 99, 99, 3, 2, 1]
x1, x2, x3 = np.split(x, [3, 5])
print(x1, x2, x3)
[1 2 3] [99 99] [3 2 1]

\(N\)个分裂点得到\(N+1\)个子数组。这种特征在np.hsplit, 和 np.vsplit用法中一样使用。

grid = np.arange(16).reshape((4, 4))
grid
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
upper, lower = np.vsplit(grid, [2])
print(upper)
print(lower)
[[0 1 2 3]
 [4 5 6 7]]
[[ 8  9 10 11]
 [12 13 14 15]]
left, right = np.hsplit(grid, [2])
print(left)
print(right)
[[ 0  1]
 [ 4  5]
 [ 8  9]
 [12 13]]
[[ 2  3]
 [ 6  7]
 [10 11]
 [14 15]]

Numpy还有np.dsplit可以在第三个维度分裂张量(三维数组),在此不在介绍与训练。

4、通用函数与计算

Numpy提供了一个简单优化的接口优化数组计算,其向量化操作在通用函数(ufunc)加持之下,大大提高效率。

4.1 Numpy的速度远远快于Python列表计算

import numpy as np
np.random.seed(0)

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(1, 10, size=5)
compute_reciprocals(values)
array([0.16666667, 1.        , 0.25      , 0.25      , 0.125     ])
big_array = np.random.randint(1, 100, size=1000000)
%timeit compute_reciprocals(big_array)
2.16 s ± 62 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

在基本的python编程下,需要几秒时间可以完成此操作。

4.2 通用函数UFuncs基本情况

向量操作与之前在Python中的数组操作完全不同。

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)
3.06 ms ± 216 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)

仅仅使用一个除法,就比之前的函数编写快得多。

np.arange(5) / np.arange(1, 6)
array([0.        , 0.5       , 0.66666667, 0.75      , 0.8       ])

通用函数不仅仅只用于一维数组,更是可以用在多维计算上:

x = np.arange(9).reshape((3, 3))
2 ** x
array([[  1,   2,   4],
       [  8,  16,  32],
       [ 64, 128, 256]], dtype=int32)

通过 ufuncs 使用向量化进行的计算几乎总是比使用 Python 循环实现的对应计算更高效,尤其是当数组规模变大时。

每当你在 Python 脚本中看到这样的循环时,你都应该考虑它是否可以被向量化表达式所取代。

4.3探索 NumPy通用函数

通用函数有两种形式,一元通用函数,对单个输入操作;二元通用函数,对两个输入操作。

数组算术用法

x = np.arange(4)
print("x     =", x)
print("x + 5 =", x + 5)
print("x - 5 =", x - 5)
print("x * 2 =", x * 2)
print("x / 2 =", x / 2)
print("x // 2 =", x // 2)  # floor division
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]

求负值,求指数,求余数的算法

print("-x     = ", -x)
print("x ** 2 = ", x ** 2)
print("x % 2  = ", x % 2)
-x     =  [ 0 -1 -2 -3]
x ** 2 =  [0 1 4 9]
x % 2  =  [0 1 0 1]

需要在计算中关注四则运算的优先级。

-(0.5*x + 1) ** 2
array([-1.  , -2.25, -4.  , -6.25])

所有符号都时NumPy 的内置函数; 如 +号就是Numpy内置的add函数

np.add(x, 2)
array([2, 3, 4, 5])

NumPy中的算术运算符号:

运算符号 相应的通用函数 ufunc 描述
+ np.add 加法 (e.g., 1 + 1 = 2)
- np.subtract 减法 (e.g., 3 - 2 = 1)
- np.negative 负数 (e.g., -2)
* np.multiply 乘法 (e.g., 2 * 3 = 6)
/ np.divide 除法 (e.g., 3 / 2 = 1.5)
// np.floor_divide 除法向下取整 (e.g., 3 // 2 = 1)
** np.power 指数运算 (e.g., 2 ** 3 = 8)
% np.mod 模/余数 (e.g., 9 % 4 = 1)

绝对值

#python中有专门的绝对值函数。
x = np.array([-2, -1, 0, 1, 2])
abs(x)
array([2, 1, 0, 1, 2])

相应NumPy 通用函数是 np.absolute, 简写为 np.abs:

np.absolute(x)
array([2, 1, 0, 1, 2])
np.abs(x)
array([2, 1, 0, 1, 2])

Numpy中的绝对值可以处理复数, 返回该复数的模:

x = np.array([3 - 4j, 4 - 3j, 2 + 0j, 0 + 1j])
np.abs(x)
array([5., 5., 2., 1.])

三角函数

# 定义一个角度数组
theta = np.linspace(0, np.pi, 3)
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, 0, 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]

指数和对数

x = [1, 2, 3]
print("x     =", x)
print("e^x   =", np.exp(x))
print("2^x   =", np.exp2(x))
print("3^x   =", np.power(3, x))
x     = [1, 2, 3]
e^x   = [ 2.71828183  7.3890561  20.08553692]
2^x   = [2. 4. 8.]
3^x   = [ 3  9 27]

指数函数的逆运算, 对数,也可以使用。 基本的 np.log 提供自然对数;

如果你想计算以2为底的对数或以10为底的对数,这些也是可用的:

x = [1, 2, 4, 10]
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.        ]

还有一些函数对微小输入保持较高的精度,如np.expm1() 和 np.log1p

x = [0, 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]

When x is very small, these functions give more precise values than if the raw np.log or np.exp were to be used.

一些特殊的通用函数

Numpy还有许多通用函数,包括双曲三角函数,比特位计算函数,比较运算符号,弧度转角度等等。另一个重要的通用函数是子模块scipy.special,在处理特殊情况,可以考虑。

from scipy import special
# Gamma函数
x = [1, 5, 10]
print("gamma(x)     =", special.gamma(x))
print("ln|gamma(x)| =", special.gammaln(x))
print("beta(x, 2)   =", special.beta(x, 2))
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, 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]

5、聚合分析: Min, Max,与其他

基本统计需要计算均值、方差、中位数,最值的计算与分析。下面来看使用Numpy进行相关计算。

5.1 数组的值求和

Python本身有求和函数sum,可以实现求和。

import numpy as np
L = np.random.random(100)
sum(L)
48.75823563456798

这种语法与 NumPy's sum 函数很像, 在这个简单的例子中是一样的:

np.sum(L)
48.758235634567995

由于Numpy的sum函数在编译码中执行操作,计算速度更快。

big_array = np.random.rand(1000000)
%timeit sum(big_array)
%timeit np.sum(big_array)
96 ms ± 6.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
1.01 ms ± 37.8 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

请注意,Python中 sum 函数与Numpy中 np.sum 功能也是不同的,后面会有说明。

5.2 最小值与最大值

与Python中相似,Numpy中也有相应的最值函数:

min(big_array), max(big_array)
(2.6322210999740747e-07, 0.9999969793097551)

NumPy相应的函数类似,但执行速度更快。

np.min(big_array), np.max(big_array)
(2.6322210999740747e-07, 0.9999969793097551)
%timeit min(big_array)
%timeit np.min(big_array)
64.5 ms ± 2.97 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
455 μs ± 25.3 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

对于 min, max, sum, 一种直接的方法是直接调用ndarray的相应方法:

print(big_array.min(), big_array.max(), big_array.sum())
2.6322210999740747e-07 0.9999969793097551 500212.70110683894

多维度处理

M = np.random.random((3, 4))
print(M)
[[0.17941645 0.70189096 0.0275724  0.25353604]
 [0.37110081 0.28781232 0.56597207 0.40980885]
 [0.81533201 0.04567107 0.08573185 0.98430074]]

默认情况下,聚合对整个数组起作用:

M.sum()
4.728145583458205

聚合更常用的是沿着多维数据不同的轴进行运算,如可以通过axis=0计算纵轴:

M.min(axis=0)
array([0.17941645, 0.04567107, 0.0275724 , 0.25353604])

该函数返回四个值,对应的是四个列,说明计算在纵向进行的。同样,对于横向计算的函数,需要如下计算:

M.max(axis=1)
array([0.70189096, 0.56597207, 0.98430074])

其他总体观察使用的聚合函数

NumPy 提供了很多聚合函数,但用法在此不细讨论。 但整个聚合函数列表如下:

函数名称 缺失值安全版本 描述
np.sum np.nansum 计算元素的和
np.prod np.nanprod 计算元素的积
np.mean np.nanmean 计算元素的平均值
np.std np.nanstd 计算元素的标准差
np.var np.nanvar 计算元素的方差
np.min np.nanmin 找出最小值
np.max np.nanmax 找出最大值
np.argmin np.nanargmin 找出最小值的索引
np.argmax np.nanargmax 找出最小值的索引
np.median np.nanmedian 计算元素的中位数
np.percentile np.nanpercentile 计算元素的分位数值
np.any N/A 验证任何一个元素为真
np.all N/A 验证所有元素位真

5.3 例子: 美国总统身高是多少?

在data文件夹中一个CSV文件,描述了美国总统的身高数据。使用Numpy进行基本分析。

NumPy 中可用的聚合函数对于汇总一组数值非常有用。举一个简单的例子,我们来看看所有美国总统的身高。 这些数据可以在 本站 president_heights.csv 文件中找到,该文件是一个简单的由逗号分隔的标签和数值列表:

import pandas as pd
data = pd.read_csv('https://www.getwage.xyz/courses/multi_variance/data/president_heights.csv')
heights = np.array(data['height(cm)'])
print(heights)
[189 170 189 163 183 171 185 168 173 183 173 173 175 178 183 193 178 173
 174 183 183 168 170 178 182 180 183 178 182 188 175 179 183 193 182 183
 177 185 188 188 182 185]

一个简要的统计内容:

print("高度均值:       ", heights.mean())
print("标准差:", heights.std())
print("最小高度:    ", heights.min())
print("最大高度:    ", heights.max())
高度均值:        179.73809523809524
标准差: 6.931843442745892
最小高度:     163
最大高度:     193

计算分位数:

print("25th percentile:   ", np.percentile(heights, 25))
print("Median:            ", np.median(heights))
print("75th percentile:   ", np.percentile(heights, 75))
25th percentile:    174.25
Median:             182.0
75th percentile:    183.0

我们看到美国总统身高中位数位182厘米。为了更清晰看到直观结果,我们进行图形展示:

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn; seaborn.set()  # set plot style
plt.hist(heights)
plt.title('Height Distribution of US Presidents')
plt.xlabel('height (cm)')
plt.ylabel('number');

png