01. NumPy

1.1 NumPy库的概述与安装

1.1.1 NumPy概述

  • NumPy几乎是一个无法回避的科学计算工具包,最常用的是它的N维数组对象,还有一些成熟的函数库,用于整合C/C++和Fortran代码的工具包、线性代数、傅里叶变换和随机数生成函数等。
  • NumPy提供了两种基本的对象:

    • ndarray:是存储单一数据类型的多维数组。
    • ufunc:是能够对数组进行处理的函数。

      1.1.2 NumPy的特点

  • 高效矩阵与数组处理。

  • 丰富的数值计算函数。
  • 实用的线性代数、傅里叶变换和随机生成函数。

    1.1.3 安装NumPy

  • 安装命令:

    1. 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库:

    1. 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.]] “””

  1. <a name="vW8Ll"></a>
  2. #### 1.2.2 ones((x, y), dtype=type)
  3. - 与zeros基本一致,唯一的差别就在于数组中所有元素为1。
  4. ```python
  5. import numpy as np
  6. arr = np.ones((4, 5))
  7. print(arr)
  8. """
  9. 运行结果:
  10. [[1. 1. 1. 1. 1.]
  11. [1. 1. 1. 1. 1.]
  12. [1. 1. 1. 1. 1.]
  13. [1. 1. 1. 1. 1.]]
  14. """
  • 若将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]] “””

  1. <a name="ZTVAD"></a>
  2. #### 1.2.3 array(lst, dtype=type)
  3. - 可以用np.array(lst)函数将一个列表转换成一个数组。
  4. ```python
  5. import numpy as np
  6. lst = [1, 2, 3, 4]
  7. arr = np.array(lst)
  8. 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.]

  1. - 此外,还可以使用array()函数定义二维数组:
  2. ```python
  3. import numpy as np
  4. arr = np.array([
  5. [1, 'A'],
  6. [2, 'B'],
  7. [3, 'C'],
  8. [4, 'D']
  9. ])
  10. print(arr)
  11. """
  12. 运行结果:
  13. [['1' 'A']
  14. ['2' 'B']
  15. ['3' 'C']
  16. ['4' 'D']]
  17. """

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]

  1. <a name="ccZMu"></a>
  2. #### 1.2.5 zeros_like(arr)
  3. - zeros_like(arr)函数会生成一个形状与arr相同的数组,但数组中的所有元素都为0。
  4. ```python
  5. import numpy as np
  6. arr = np.array([
  7. [1, 2, 3],
  8. [4, 5, 6],
  9. [7, 8, 9]
  10. ])
  11. zero_arr = np.zeros_like(arr)
  12. print(zero_arr)
  13. """
  14. 运行结果:
  15. [[0 0 0]
  16. [0 0 0]
  17. [0 0 0]]
  18. """

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.]

  1. <a name="g3e7o"></a>
  2. #### 1.2.7 random.normal(loc=0.0, scale=1.0, size=None)
  3. - random.normal(loc=0.0, scale=1.0, size=None)函数会从正态分布中抽取随机样本生成一个数组。
  4. - loc:分布的平均值。
  5. - scala:标注差。
  6. - size:数组的形状。
  7. ```python
  8. import numpy as np
  9. arr = np.random.normal(size=(2,2)) # 生成一个2*2的随机数组。
  10. print(arr)
  11. """
  12. 运行结果:
  13. [[-0.25212173 -0.71369917]
  14. [-0.76119745 0.37228655]]
  15. """

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

  1. <a name="fqEFh"></a>
  2. #### 1.3.2 array.shape
  3. - array.shape可以获取一个数组的形状。
  4. ```python
  5. import numpy as np
  6. arr = np.array([
  7. [1, 'A'],
  8. [2, 'B'],
  9. [3, 'C'],
  10. [4, 'D']
  11. ])
  12. print(arr.shape) # (4, 2)
  • 结果(4, 2)的解读:

    • 返回的是一个元组,元组中有几个成员就代表这是一个几维数组。这里arr.ndim = 2,因此shape的结果是一个二元组。
    • 4:代表这个数组有4行。
    • 2:代表这个数组有2列。

      1.3.3 array.size

  • 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

  1. <a name="zz5gb"></a>
  2. #### 1.3.4 array.reshape(x, y)
  3. - array.reshape(x, y)函数用于将数组的维度重置为x行y列。
  4. ```python
  5. import numpy as np
  6. arr1 = np.arange(100)
  7. 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]
  8. print(arr1.shape) # (100,)
  9. arr2 = arr1.reshape(10, 10)
  10. print(arr2)
  11. """
  12. [[ 0 1 2 3 4 5 6 7 8 9]
  13. [10 11 12 13 14 15 16 17 18 19]
  14. [20 21 22 23 24 25 26 27 28 29]
  15. [30 31 32 33 34 35 36 37 38 39]
  16. [40 41 42 43 44 45 46 47 48 49]
  17. [50 51 52 53 54 55 56 57 58 59]
  18. [60 61 62 63 64 65 66 67 68 69]
  19. [70 71 72 73 74 75 76 77 78 79]
  20. [80 81 82 83 84 85 86 87 88 89]
  21. [90 91 92 93 94 95 96 97 98 99]]
  22. """
  23. 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]] “””

  1. <a name="eYEka"></a>
  2. ### 1.4 数组的索引和切片
  3. <a name="UbEl4"></a>
  4. #### 1.4.1 数组的索引
  5. - 数组的索引与列表的索引基本一致。
  6. ```python
  7. import numpy as np
  8. arr = np.arange(10)
  9. print(arr) # [0 1 2 3 4 5 6 7 8 9]
  10. print(arr[3]) # 3
  11. print(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]

  1. - 而对于二维数组而言,数组的切片不同于列表。列表只能在横方向上切片,而数组在横方向和纵方向上都可以切片。
  2. - 示例:取arr1横方向上的[3, 8]步长为2,纵方向上的[0, 10]步长为3
  3. ```python
  4. import numpy as np
  5. arr1 = np.arange(100).reshape(10, 10)
  6. arr2 = arr1[3:8:2, 0:10:3]
  7. print(arr2)
  8. """
  9. 运行结果:
  10. [[30 33 36 39]
  11. [50 53 56 59]
  12. [70 73 76 79]]
  13. """
  • 数组中特有的操作: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]

  1. <a name="CsgSB"></a>
  2. #### 1.4.3 数组切片的重要注意点
  3. - 列表中切片是从原列表中拷贝[start, end)的数据给一块新的内存空间,因此对切片后的数据进行操作不会影响到原来的数据。
  4. ```python
  5. lst = [x for x in range(10)]
  6. lst_slice = lst[5:8]
  7. lst_slice[1] = 999
  8. print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  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]

  1. <a name="UAx5o"></a>
  2. ### 1.5 数组元素的筛选
  3. <a name="PtEjP"></a>
  4. #### 1.5.1 逻辑筛选
  5. - 可以直接对array进行一个逻辑运算,它会自动对数组中的元素进行计算,并返回一个新的数组,其他包含每个元素逻辑运算的结果。
  6. - 示例:判断一个数组中哪些元素是偶数,哪些不是:
  7. ```python
  8. import numpy as np
  9. arr1 = np.array([7, 1, 4, 5, 2])
  10. arr2 = arr1 % 2 == 0
  11. print(arr2) # [False False True False True]
  • 接着将数据数组与布尔数组合并即可实现过滤。
    • 过滤规则:将True对应的数据留下(符合条件的数据);将False对应的数据删除(不符合条件的数据)
  • 示例:过滤出arr1中所有的偶数。

    1. arr3 = arr1[arr2]
    2. 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.]]

  1. <a name="fsvE6"></a>
  2. #### 1.5.3 筛选练习
  3. - 现有列表:`lst = [1, 'A', 2, 'B', 3, 'A', 4, 'B', 5, 'A', 6, 'B']`
  4. - 将其转换为六行两列的数组,并筛选出A的数据。
  5. - 代码实现:
  6. - 导入NumPy库。
  7. ```python
  8. import 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. - 判断纵方向上1号索引位上的元素是否为A
  2. ```python
  3. screening_criteria = matrix_data[::, 1] == 'A'
  4. 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’]] “””

  1. <a name="FjDWd"></a>
  2. ### 1.6 一些内置的统计方法
  3. <a name="VOfSs"></a>
  4. #### 1.6.1 mean()
  5. - mean()函数用于求数组中元素的平均值。
  6. ```python
  7. import numpy as np
  8. arr = np.arange(10)
  9. avg = arr.mean()
  10. print(avg) # 4.5

1.6.2 sum()

  • sum()函数用于对数组内所有元素求和。 ```python import numpy as np

arr = np.arange(10) all = arr.sum() print(all) # 45

  1. <a name="emu1R"></a>
  2. #### 1.6.3 max()/min()
  3. - max()函数用于对数组内所有元素求最大值。
  4. - min()函数用于对数组内所有元素求最小值。
  5. ```python
  6. import numpy as np
  7. arr = np.arange(10)
  8. print(arr.max()) # 9
  9. print(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]

  1. - axis没有缺省值,如果不指定就不会触发分组,而是将所有数据直接触发统计计算。
  2. <a name="GFnhE"></a>
  3. ### 1.7 数组转置
  4. - 数组转置通过属性T实现。
  5. ```python
  6. import numpy as np
  7. arr = np.arange(1, 10).reshape(3, -1)
  8. print(arr)
  9. """
  10. [[1 2 3]
  11. [4 5 6]
  12. [7 8 9]]
  13. """
  14. print(arr.T)
  15. """
  16. [[1 4 7]
  17. [2 5 8]
  18. [3 6 9]]
  19. """

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

    1. 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 “””

  1. - 可以通过index属性为数据自定义数据标签。(数据标签是可以重复的,后面的标签不会覆盖前面的标签)
  2. ```python
  3. import pandas as pd
  4. se = pd.Series(
  5. [5, 1, 3, 7, 2, 6],
  6. index=['a', 'b', 'c', 'd', 'a', 'c']
  7. )
  8. print(se)
  9. """
  10. 运行结果:
  11. a 5
  12. b 1
  13. c 3
  14. d 7
  15. a 2
  16. c 6
  17. dtype: int64
  18. """

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

  1. - 假如一个数据标签对应多个数据,那么会返回包含这个数据序列对应的所有数据的新序列。
  2. ```python
  3. import pandas as pd
  4. se = pd.Series([5, 1, 3, 4, 6], ['a', 'b', 'c', 'a', 'c'])
  5. print(se['a'])
  6. """
  7. 运行结果:
  8. a 5
  9. a 4
  10. dtype: int64
  11. """
  • 除此之外,还可以用iloc[index]函数通过索引位来获取元素。 ```python import pandas as pd

se = pd.Series([5, 1, 3, 4, 6]) print(se.iloc[3]) # 4

  1. - <br />
  2. - <br />
  3. - <br />
  4. - <br />
  5. - <br />
  6. - <br />
  7. - <br />
  8. - <br />
  9. - <br />
  10. - 汇总统计:
  11. - 5出现2次,3出现2次,1出现两次。
  12. ```python
  13. import pandas as pd
  14. se = pd.Series([5, 5, 3, 3, 2])
  15. print(se.value_counts())
  16. """
  17. 运行结果:
  18. 5 2
  19. 3 2
  20. 2 1
  21. dtype: int64
  22. """
  • 方式二: ```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}) ```



  • 阿萨的

    2.3 DataFrame

    03. Matplotlib