01. NumPy
1.1 NumPy库的概述与安装
1.1.1 NumPy概述
- NumPy几乎是一个无法回避的科学计算工具包,最常用的是它的N维数组对象,还有一些成熟的函数库,用于整合C/C++和Fortran代码的工具包、线性代数、傅里叶变换和随机数生成函数等。
NumPy提供了两种基本的对象:
高效矩阵与数组处理。
- 丰富的数值计算函数。
-
1.1.3 安装NumPy
安装命令:
pip install numpy
这里可能安装失败,Python安装第三方库失败基本上都是网络问题,可以换源解决。
- 国内常见的源:
- 换源安装命令:
pip install 第三方模块名 -i 镜像源 - 示例:用清华源安装numpy:
pip install numpy -i [https://pypi.tuna.tsinghua.edu.cn/simple/](https://pypi.tuna.tsinghua.edu.cn/simple/) 安装完成后,在编码时需要先导入NumPy库:
import numpy as np
1.2 NumPy中数组的创建
1.2.1 zeros((x, y), dtype=type)
np.zero((x, y))函数可以用于生成一个x行y列的数组,且数组中所有元素为0。 ```python import numpy as np
arr = np.zeros((4, 5)) print(arr)
“”” 运行结果: [[0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.]] “””
<a name="vW8Ll"></a>#### 1.2.2 ones((x, y), dtype=type)- 与zeros基本一致,唯一的差别就在于数组中所有元素为1。```pythonimport numpy as nparr = np.ones((4, 5))print(arr)"""运行结果:[[1. 1. 1. 1. 1.][1. 1. 1. 1. 1.][1. 1. 1. 1. 1.][1. 1. 1. 1. 1.]]"""
- 若将dtype指定为bool,则将得到一个全True的数组。(zeros也有这样的操作,得到全False的数组) ```python import numpy as np
arr = np.ones((4, 5), dtype=bool) print(arr)
“”” 运行结果: [[ True True True True True] [ True True True True True] [ True True True True True] [ True True True True True]] “””
<a name="ZTVAD"></a>#### 1.2.3 array(lst, dtype=type)- 可以用np.array(lst)函数将一个列表转换成一个数组。```pythonimport numpy as nplst = [1, 2, 3, 4]arr = np.array(lst)print(arr) # [1 2 3 4]
- 同时,还可以指定dtype,为数组中的元素明确类型。 ```python import numpy as np
lst = [1, 2, 3, 4] arr = np.array(lst, dtype=float) print(arr) # [1. 2. 3. 4.]
- 此外,还可以使用array()函数定义二维数组:```pythonimport numpy as nparr = np.array([[1, 'A'],[2, 'B'],[3, 'C'],[4, 'D']])print(arr)"""运行结果:[['1' 'A']['2' 'B']['3' 'C']['4' 'D']]"""
1.2.4 arange(start, end, step)
- np.arange(start, end, step)函数用于生成从start开始到end结束的一段步长为step的数组。(步长缺省为1) ```python import numpy as np
arr = np.arange(1, 10, 3) print(arr) # [1 4 7]
<a name="ccZMu"></a>#### 1.2.5 zeros_like(arr)- zeros_like(arr)函数会生成一个形状与arr相同的数组,但数组中的所有元素都为0。```pythonimport numpy as nparr = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])zero_arr = np.zeros_like(arr)print(zero_arr)"""运行结果:[[0 0 0][0 0 0][0 0 0]]"""
1.2.6 linspace(start, end, n)
- linspace(start, end, n)会生成一个从start到end的等差数列,中间的数据有n个。
- 注意:与Python中其他数据类型都不同,linspace(start, end, n)生成的数据不是[start, end)的,而是[start, end]的。 ```python import numpy as np
arr = np.linspace(5, 25, 3) print(arr) # [ 5. 15. 25.]
<a name="g3e7o"></a>#### 1.2.7 random.normal(loc=0.0, scale=1.0, size=None)- random.normal(loc=0.0, scale=1.0, size=None)函数会从正态分布中抽取随机样本生成一个数组。- loc:分布的平均值。- scala:标注差。- size:数组的形状。```pythonimport numpy as nparr = np.random.normal(size=(2,2)) # 生成一个2*2的随机数组。print(arr)"""运行结果:[[-0.25212173 -0.71369917][-0.76119745 0.37228655]]"""
1.3 数组的规模
1.3.1 array.ndim
- array.ndim可以获取一个数组的维度。 ```python import numpy as np
arr = np.array([ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]) print(arr.ndim) # 2
<a name="fqEFh"></a>#### 1.3.2 array.shape- array.shape可以获取一个数组的形状。```pythonimport numpy as nparr = np.array([[1, 'A'],[2, 'B'],[3, 'C'],[4, 'D']])print(arr.shape) # (4, 2)
结果(4, 2)的解读:
array.size可以获取一个数组的大小,size实际上就是sharp得到的(x, y)中x * y的结果。 ```python import numpy as np
arr = np.array([ [1, ‘A’], [2, ‘B’], [3, ‘C’], [4, ‘D’] ]) print(arr.size) # 8
<a name="zz5gb"></a>#### 1.3.4 array.reshape(x, y)- array.reshape(x, y)函数用于将数组的维度重置为x行y列。```pythonimport numpy as nparr1 = np.arange(100)print(arr1) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]print(arr1.shape) # (100,)arr2 = arr1.reshape(10, 10)print(arr2)"""[[ 0 1 2 3 4 5 6 7 8 9][10 11 12 13 14 15 16 17 18 19][20 21 22 23 24 25 26 27 28 29][30 31 32 33 34 35 36 37 38 39][40 41 42 43 44 45 46 47 48 49][50 51 52 53 54 55 56 57 58 59][60 61 62 63 64 65 66 67 68 69][70 71 72 73 74 75 76 77 78 79][80 81 82 83 84 85 86 87 88 89][90 91 92 93 94 95 96 97 98 99]]"""print(arr2.shape) # (10, 10)
- 若x和y中有一个指定为了-1,则具体的形状会根据填了具体数值的进行自动推算。(x和y不能同时指定为-1) ```python import numpy as np
arr = np.arange(100) arr1 = arr.reshape(10, -1) print(arr1) “”” 运行结果: [[ 0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 25 26 27 28 29] [30 31 32 33 34 35 36 37 38 39] [40 41 42 43 44 45 46 47 48 49] [50 51 52 53 54 55 56 57 58 59] [60 61 62 63 64 65 66 67 68 69] [70 71 72 73 74 75 76 77 78 79] [80 81 82 83 84 85 86 87 88 89] [90 91 92 93 94 95 96 97 98 99]] “””
arr2 = arr.reshape(-1, 20) print(arr2) “”” 运行结果: [[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39] [40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59] [60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79] [80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]] “””
<a name="eYEka"></a>### 1.4 数组的索引和切片<a name="UbEl4"></a>#### 1.4.1 数组的索引- 数组的索引与列表的索引基本一致。```pythonimport numpy as nparr = np.arange(10)print(arr) # [0 1 2 3 4 5 6 7 8 9]print(arr[3]) # 3print(arr[6:9]) # [6 7 8]
1.4.2 数组的切片
- 对于一个一维数组而言,其切片在操作上与列表没有什么区别。 ```python import numpy as np
arr = np.arange(10) print(arr[5:8]) # [5 6 7]
- 而对于二维数组而言,数组的切片不同于列表。列表只能在横方向上切片,而数组在横方向和纵方向上都可以切片。- 示例:取arr1横方向上的[3, 8]步长为2,纵方向上的[0, 10]步长为3。```pythonimport numpy as nparr1 = np.arange(100).reshape(10, 10)arr2 = arr1[3:8:2, 0:10:3]print(arr2)"""运行结果:[[30 33 36 39][50 53 56 59][70 73 76 79]]"""
- 数组中特有的操作:arr[:]代表的是arr中所有的元素,会以此遍历arr中所有的元素并进行指定操作。
- 如:将arr中所有的元素加一。 ```python import numpy as np
arr = np.arange(10) print(arr) # [0 1 2 3 4 5 6 7 8 9]
arr[:] += 1 print(arr) # [ 1 2 3 4 5 6 7 8 9 10]
<a name="CsgSB"></a>#### 1.4.3 数组切片的重要注意点- 列表中切片是从原列表中拷贝[start, end)的数据给一块新的内存空间,因此对切片后的数据进行操作不会影响到原来的数据。```pythonlst = [x for x in range(10)]lst_slice = lst[5:8]lst_slice[1] = 999print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]print(lst_slice) # [5, 999, 7]
- 而数组则是将切片的那部分内存地址给到新的变量,因此对切片后的数据进行操作会影响原有的数组。 ```python import numpy as np
arr = np.arange(10) print(arr) # [0 1 2 3 4 5 6 7 8 9]
arr_slice = arr[5:8] arr_slice[1] = 999
print(arr_slice) # [ 5 999 7] print(arr) # [ 0 1 2 3 4 5 999 7 8 9]
<a name="UAx5o"></a>### 1.5 数组元素的筛选<a name="PtEjP"></a>#### 1.5.1 逻辑筛选- 可以直接对array进行一个逻辑运算,它会自动对数组中的元素进行计算,并返回一个新的数组,其他包含每个元素逻辑运算的结果。- 示例:判断一个数组中哪些元素是偶数,哪些不是:```pythonimport numpy as nparr1 = np.array([7, 1, 4, 5, 2])arr2 = arr1 % 2 == 0print(arr2) # [False False True False True]
- 接着将数据数组与布尔数组合并即可实现过滤。
- 过滤规则:将True对应的数据留下(符合条件的数据);将False对应的数据删除(不符合条件的数据)
示例:过滤出arr1中所有的偶数。
arr3 = arr1[arr2]print(arr3) # [4 2]
1.5.2 条件筛选
示例:现有一个名字数组与成绩数组(【语、数、英、科】与90分的正负值),成员与成绩是按照索引位对应的。
name = ['Bob', 'Will', 'Bob', 'Joe']grade = [[-3, 2, 0, -1], [1, 2, 3, -4], [2.5, 1.7, -0.2, 1], [-8, -4, 9, 10]]
- 要求:输入Bob的四门课成绩数据以及英语科学的数据。 ```python import numpy as np
列表数据
name = [‘Bob’, ‘Will’, ‘Jack’, ‘Joe’] grade = [[-3, 2, 0, -1], [1, 2, 3, -4], [2.5, 1.7, -0.2, 1], [-8, -4, 9, 10]]
封装成数组
name_arr = np.array(name, dtype=str) grade_arr = np.array(grade, dtype=float)
筛选出Bob的全科成绩(逻辑筛选)
print(grade_arr[name_arr == ‘Bob’]) # [[-3. 2. 0. -1.]]
筛选出Bob的全科成绩(逻辑筛选 + 纵向切片)
print(grade_arr[name_arr == ‘Bob’, 2:]) # [[ 0. -1.]]
<a name="fsvE6"></a>#### 1.5.3 筛选练习- 现有列表:`lst = [1, 'A', 2, 'B', 3, 'A', 4, 'B', 5, 'A', 6, 'B']`- 将其转换为六行两列的数组,并筛选出A的数据。- 代码实现:- 导入NumPy库。```pythonimport numpy as np
- 将列表数据转换为矩阵数据。 ```python lst = [1, ‘A’, 2, ‘B’, 3, ‘A’, 4, ‘B’, 5, ‘A’, 6, ‘B’] matrix_data = np.array(lst).reshape(6, 2) print(matrix_data)
“”” 运行结果: [[‘1’ ‘A’] [‘2’ ‘B’] [‘3’ ‘A’] [‘4’ ‘B’] [‘5’ ‘A’] [‘6’ ‘B’]] “””
- 判断纵方向上1号索引位上的元素是否为A。```pythonscreening_criteria = matrix_data[::, 1] == 'A'print(screening_criteria) # [ True False True False True False]
- 过滤出最终数据。 ```python final_data = matrix_data[screening_criteria] print(final_data)
“”” 运行结果: [[‘1’ ‘A’] [‘3’ ‘A’] [‘5’ ‘A’]] “””
<a name="FjDWd"></a>### 1.6 一些内置的统计方法<a name="VOfSs"></a>#### 1.6.1 mean()- mean()函数用于求数组中元素的平均值。```pythonimport numpy as nparr = np.arange(10)avg = arr.mean()print(avg) # 4.5
1.6.2 sum()
- sum()函数用于对数组内所有元素求和。 ```python import numpy as np
arr = np.arange(10) all = arr.sum() print(all) # 45
<a name="emu1R"></a>#### 1.6.3 max()/min()- max()函数用于对数组内所有元素求最大值。- min()函数用于对数组内所有元素求最小值。```pythonimport numpy as nparr = np.arange(10)print(arr.max()) # 9print(arr.min()) # 0
1.6.4 axis属性
- axis可以按照行或列进行分组,再进行统计计算。
- axis=0:按列进行分组计算。
- axis=1:按行进行分组计算。
- 示例:计算arr每一行的总和与最大值,以及每一列的平均值与最小值。 ```python import numpy as np
arr = np.arange(25).reshape(5, -1)
print(arr.sum(axis=1)) # [ 10 35 60 85 110] print(arr.max(axis=1)) # [ 4 9 14 19 24]
print(arr.mean(axis=0)) # [10. 11. 12. 13. 14.] print(arr.min(axis=0)) # [0 1 2 3 4]
- axis没有缺省值,如果不指定就不会触发分组,而是将所有数据直接触发统计计算。<a name="GFnhE"></a>### 1.7 数组转置- 数组转置通过属性T实现。```pythonimport numpy as nparr = np.arange(1, 10).reshape(3, -1)print(arr)"""[[1 2 3][4 5 6][7 8 9]]"""print(arr.T)"""[[1 4 7][2 5 8][3 6 9]]"""
02. Pandas
2.1 NumPy库的概述与安装
2.1.1 NumPy概述
- Pandas全名Python Data Analysis Library,是基于NumPy的一种工具,还可以结合matplotlib来使用。该工具是为了解决数据分析任务而创建的。
- Pandas纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。
- Pandas提供了诸多的数据处理方法和时间序列的操作方法,是当下最重要的Python科学运算模块之一。
- Pandas提供了大量能使我们快速便捷地处理数据的函数和方法,比如数据读取,索引切分,分组,时间序列,重塑,合并。
- 对各类数据读取,包括csv,json,excel,txt,api,html,数据库等等;可以把数据高效简单存储成多种格式,包括hdfs,csv,excel等。
Pandas中最重要的两个数据结构是DataFrame和Series,可以对数据进行简单的处理。
2.1.2 安装Pandas
pip install pandas
2.2 Series序列
2.2.1 序列的概述与创建
Series是Pandas中的数据结构之一,是一种类似于维数组的对象,由一组数据以及一组与之相关的数据标签(即索引组成)
- Series可以通过Pandas库中的Series()方法生成。
- 数据前面的0、1、2、3、4就是数据标签。 ```python import pandas as pd
lst = [5, 1, 3, 7, 2] se = pd.Series(lst) print(se)
“”” 运行结果: 0 5 1 1 2 3 3 7 4 2 dtype: int64 “””
- 可以通过index属性为数据自定义数据标签。(数据标签是可以重复的,后面的标签不会覆盖前面的标签)```pythonimport pandas as pdse = pd.Series([5, 1, 3, 7, 2, 6],index=['a', 'b', 'c', 'd', 'a', 'c'])print(se)"""运行结果:a 5b 1c 3d 7a 2c 6dtype: int64"""
2.2.2 序列的索引
- 序列中的值可以通过“序列名[“数据标签”]”获取。
- 假如一个数据标签只对应一个数据,那么会直接获取到这个数据。 ```python import pandas as pd
se = pd.Series([5, 1, 3, 4, 6], [‘a’, ‘b’, ‘c’, ‘d’, ‘e’]) print(se[‘c’]) # 3
- 假如一个数据标签对应多个数据,那么会返回包含这个数据序列对应的所有数据的新序列。```pythonimport pandas as pdse = pd.Series([5, 1, 3, 4, 6], ['a', 'b', 'c', 'a', 'c'])print(se['a'])"""运行结果:a 5a 4dtype: int64"""
- 除此之外,还可以用iloc[index]函数通过索引位来获取元素。 ```python import pandas as pd
se = pd.Series([5, 1, 3, 4, 6]) print(se.iloc[3]) # 4
- <br />- <br />- <br />- <br />- <br />- <br />- <br />- <br />- <br />- 汇总统计:- 5出现2次,3出现2次,1出现两次。```pythonimport pandas as pdse = pd.Series([5, 5, 3, 3, 2])print(se.value_counts())"""运行结果:5 23 22 1dtype: int64"""
- 方式二: ```python import pandas as pd from collections import Counter
se = pd.Series([5, 5, 3, 3, 2]) print(Counter(se)) # Counter({5: 2, 3: 2, 2: 1}) ```
