以下内容主要学习自《利用Python进行数据分析》
第4章 NumPy基础(3)
NumPy是Numerical Python的简称,它是目前Python数值计算中最为重要的基础包。大多数计算包都提供了基于Numpy的科学函数功能,将NumPy的数组对象作为数据交换的通用语言。
本章将介绍NumPy数组的基础操作。虽然深入理解NumPy对于大部分数据分析应用并不是必需的,但是精通基于数组的编程和思维是成为Python科学计算专家的第一步。
![](https://img.haomeiwen.com/i1284966/3c2e5e7da8278768.png)
ndarray运算
单数组的算术
掌握NumPy数组之所以重要,是因为它允许你进行批量操作而不需任何for循环。NumPy称这种特性为向量化。
标量算术
所谓的标量,简单理解就是具体数值。数组与标量的算术操作(加减乘除),会影响到数组的每一个元素。
In [10]: arr = np.arange(12).reshape(3,4)
In [12]: arr
Out[12]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [11]: arr + 1
Out[11]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
In [13]: arr * 0.5
Out[13]:
array([[0. , 0.5, 1. , 1.5],
[2. , 2.5, 3. , 3.5],
[4. , 4.5, 5. , 5.5]])
一元通用函数
假设x是一个ndarray数组,那么下面的一元通用函数会影响到数组中的每一个元素。
函数名 | 描述 |
---|---|
np.abs(x) | 绝对值 |
np.sqrt(x) | 平方根 |
np.square(x) | 平方 |
np.exp(x) | 自然指数 |
np.[log|log10|log2](x) | 对数 |
np.sign(x) | 符号值(1正数、0零、-1负数) |
np.ceil(x) | 最大整数值 |
np.floor(x) | 最小整数值 |
np.[sin|cos|tan](x) | 三角函数 |
np.[arcsin|arccos|arctan](x) | 反三角函数 |
np.isnan(x) | 是否NaN |
同尺寸数组的算术
任何在两个等尺寸数组之间的算术操作都应用了逐元素操作的方式。
四则运算
可以对两个数组直接应用四则运算:
# 生成随机数组1
In [1]: arr1 = np.random.randint(low=0, high=20, size=(2,5))
In [2]: arr1
Out[2]:
array([[14, 12, 7, 5, 6],
[13, 2, 3, 15, 7]])
# 生成随机数组2
In [3]: arr2 = np.random.randint(low=0, high=20, size=(2,5))
In [4]: arr2
Out[4]:
array([[ 9, 0, 4, 19, 16],
[11, 9, 17, 3, 3]])
# 两个同尺寸数组相加
In [5]: arr1+arr2
Out[5]:
array([[23, 12, 11, 24, 22],
[24, 11, 20, 18, 10]])
# 两个同尺寸数组相减
In [6]: arr1-arr2
Out[6]:
array([[ 5, 12, 3, -14, -10],
[ 2, -7, -14, 12, 4]])
# 两个同尺寸数组相乘
In [7]: arr1 * arr2
Out[7]:
array([[126, 0, 28, 95, 96],
[143, 18, 51, 45, 21]])
# 两个同尺寸数组相除(注意,当被0除时,会有一个警告、但不会报错)
In [8]: arr1/arr2
RuntimeWarning: divide by zero encountered in true_divide
Out[8]:
array([[1.55555556, inf, 1.75 , 0.26315789, 0.375 ],
[1.18181818, 0.22222222, 0.17647059, 5. , 2.33333333]])
比较运算
同尺寸数组之间的比较,会产生一个布尔值数组:
In [9]: arr1
Out[9]:
array([[14, 12, 7, 5, 6],
[13, 2, 3, 15, 7]])
In [10]: arr2
Out[10]:
array([[ 9, 0, 4, 19, 16],
[11, 9, 17, 3, 3]])
In [11]: arr1>arr2
Out[11]:
array([[ True, True, True, False, False],
[ True, False, False, True, True]])
二元通用函数
假设x, y是同尺寸的ndarray数组,那么下面的二元通用函数会逐元素的进行运算。
函数名 | 描述 |
---|---|
np.add(x, y) | 两个数组相加 |
np.subtractx, y) | 两个数组相减 |
np.multiply(x, y) | 两个数组相乘 |
np.divide(x, y) | 两个数组相除 |
np.floor_divide(x, y) | 两个数组整除(放弃余数) |
np.power(x, y) | 将第二个数组作为第一个数组的幂次方 |
np.[maximum|fmax](x, y) | 逐元素计算最大值,fmax忽略NaN |
np.[minimum|fmin](x, y) | 逐元素计算最小值,fmin忽略NaN |
np.mod(x, y) | 按元素求模,即求相除后的余数 |
np.copysign(x, y) | 将第一个数组的符号改为第二个数组的符号(正负号) |
np.[greater|greater_equal](x, y) | 比较两个数组,返回布尔值数组 |
np.[less|less_equal](x, y) | 比较两个数组,返回布尔值数组 |
np.[equal|not_equal](x, y) | 比较两个数组,返回布尔值数组 |
np.logical_and(x, y) | 逻辑与 |
np.logical_or(x, y) | 逻辑或 |
np.logical_xor(x, y) | 逻辑异或 |
条件逻辑算术
NumPy的np.where函数
是三元表达式x if condition eles y
的向量化版本。在详细解释where之前,我们先看看如下的示例代码:
In [1]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
In [2]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
In [3]: cond = np.array([True, False, True, True, False])
假设cond中的元素为True时,我们去xarr中的对应元素,否则取yarr中的对应元素。常规情况下我们使用列表推导式来完成,如下:
In [3]: result = [(x if c else y)
...: for x, y, c in zip(xarr, yarr, cond)]
In [4]: result
Out[4]: [1.1, 2.2, 1.3, 1.4, 2.5]
以上虽然到达了目的,但有两个问题:首先,如果数组很大的话,速度会很慢(因为所有的工作都是通过Python的解释器完成的);其次,当数组是多维时就无法奏效了。此时,np.where
就派上用场了。
In [5]: result = np.where(cond, xarr, yarr)
In [6]: result
Out[6]: array([1.1, 2.2, 1.3, 1.4, 2.5])
另外,np.where
的第二个和第三个参数除了是数组,还可以是标量。假设我们有一个数组,我们想把其中正值都替换为2、负值都替换为-2,那么代码如下:
# 创建一个2X3的随机数数组
In [1]: arr = np.random.randn(2, 3)
In [2]: arr
Out[2]:
array([[-0.43739758, 0.96547377, 0.15388708],
[-1.49166677, -1.19171251, -0.15982192]])
# 逐元素比较arr是否大于零,结果作为条件
# 为True,就赋值2
# 为False,就赋值-2
In [3]: np.where(arr>0, 2, -2)
Out[3]:
array([[-2, 2, 2],
[-2, -2, -2]])
不同尺寸数组的操作:广播特性
ndarray统计方法
NumPy提供了如下的统计方法(聚合函数)
方法 | 描述 |
---|---|
sum | 累计和 |
mean | 求平均值 |
std, var | 求标准差、方差 |
min, max | 求最大值、最小值 |
argmin, argmax | 求最大值、最小值出现的位置 |
cumsum | 计算累计值 |
cumprod | 计算累计积 |
注意:以上的方法既可以调用ndarray实例的方法(arr.sum()),也可以使用NumPy顶层的函数(np.sum(arr))。
# 创建一个最小值-5、最大值5的3X4的随机数组
In [1]: arr = np.random.randint(-5,5,(3, 4))
In [2]: arr
Out[2]:
array([[ 1, 0, 3, -1],
[ 0, 0, 0, 2],
[ 0, -2, 3, 2]])
# 对数组求和,此处是调用实例的方法来求和的。
In [3]: arr.sum()
Out[3]: 8
# 与上面的效果相同,但此处是调用NumPy的顶层函数来求和的。
In [4]: np.sum(arr)
Out[4]: 8
上面列出的统计方法(聚合函数),均有可选参数axis。如果不指定这个参数,那么就是对所有的元素进行聚合运算。如果为axis参数指定值,就是在给定轴上进行聚合运算,并得到下降一个维度的数组。
In [5]: arr
Out[5]:
array([[ 1, 0, 3, -1],
[ 0, 0, 0, 2],
[ 0, -2, 3, 2]])
# 求整个数组的最大值
In [6]: np.max(arr)
Out[6]: 3
# 在0轴上求最大值(按行)
In [7]: np.max(arr, axis=0)
Out[7]: array([1, 0, 3, 2])
# 在1轴上求最大值(按列)
In [8]: np.max(arr, axis=1)
Out[8]: array([3, 2, 3])
ndarray集合操作
获取唯一值
获取唯一值的准确说法是“获取不重复的值”,如下:
# 创建随机数数组,每个元素介于0~5,共有10个元素。
In [1]: arr = np.random.randint(0, 5, (10,))
In [2]: arr
Out[2]: array([2, 1, 3, 1, 0, 2, 3, 3, 0, 2])
In [3]: np.unique(arr) # 获取不重复的元素
Out[3]: array([0, 1, 2, 3])
计算交集/并集
# 创建随机数数组,每个元素介于0~5,共有10个元素。
In [1]: arr1 = np.random.randint(0, 5, (10,))
In [2]: arr1
Out[2]: array([2, 1, 4, 0, 2, 0, 3, 4, 2, 0])
# 创建随机数数组,每个元素介于3~8,共有10个元素。
In [3]: arr2 = np.random.randint(3, 8, (10,))
In [4]: arr2
Out[4]: array([5, 3, 7, 3, 6, 6, 6, 7, 6, 7])
# 计算两个数组的交集
In [5]: np.intersect1d(arr1, arr2)
Out[5]: array([3])
# 计算两个数组的交集
In [6]: np.union1d(arr1, arr2)
Out[6]: array([0, 1, 2, 3, 4, 5, 6, 7])
计算包含关系
In [1]: arr = np.array([2, 1, 4, 0, 2, 0, 3, 4, 2, 0])
In [2]: np.in1d(arr, [1, 3, 5])
Out[2]:
array([False, True, False, False, False, False, True, False, False,
False])
集合操作函数
函数 | 描述 |
---|---|
np.unique(x) | 计算唯一值,并排序 |
np.intersect1d(x, y) | 计算交集,并排序 |
np.union1d(x, y) | 计算并集,并排序 |
np.in1d(x, y) | 计算x的元素是否包含在y中,返回布尔数组 |
np.setdiff1d(x, y) | 计算差集,在x中但不在y中元素 |
np.setxor1d(x, y) | 计算异或集,在x或y中、但不属于xy交集的元素 |
线性代数
在NumPy中,使用dot方法
计算矩阵的点积。
In [1]: x = np.array([[1.,2., 3.], [4., 5., 6.]])
In [3]: y = np.array([[6.,2], [-1., 7], [3, 1]])
In [3]: x.dot(y)
Out[3]:
array([[13., 19.],
[37., 49.]])
In [4]: np.dot(x, y)
Out[4]:
array([[13., 19.],
[37., 49.]])
Numpy的numpy.linalg模块
拥有矩阵分解的标准函数集。
函数 | 描述 |
---|---|
diag | 将一个矩阵的对角元素作为一维数组返回;或将一维数组转换为矩阵 |
dot | 矩阵点积 |
trace | 计算对角元素和 |
det | 计算矩阵的行列式 |
eig | 计算矩阵的特征值和特征向量 |
inv | 计算逆矩阵 |
pinv | 计算矩阵的Moore-Penrose伪逆 |
qr | 计算QR分解 |
svd | 计算奇异值分解 |
solve | 求解x的线性系统Ax=b,其中A是矩阵 |
lstsq | 计算Ax=b的最小二乘解 |
由于线性代数的示例较复杂,所以上述标准函数库用法,请参考NumPy的官方文档。
网友评论