【数据分析“三剑客”】—— NumPy

本系列数据分析博客使用jupyter notebook作为开发环境,如果你还不是很熟悉jupyter notebook,我推荐你可以先花几十分钟实现学习一下我关于python开发环境搭建介绍的博客:python开发环境搭建------pycharm和jupyternotebook_jupyter跟pycharm代码-CSDN博客

Python 数据分析领域有被称为"三剑客"的三个非常流行的库,它们分别是:

  1. NumPy: NumPy 是一个强大的数值计算库,它是许多科学计算包的基础,包括 Pandas。NumPy 提供了一个高性能的多维数组对象 ndarray,以及对数组进行快速数学运算的功能。它还包括用于线性代数、傅立叶变换和随机数生成等功能的函数,是进行大规模数值计算的基础工具。

  2. Pandas: Pandas 是一个开源的 Python 库,提供了大量易于使用的数据结构和数据分析工具。它的核心功能包括 DataFrame(二维表格型数据结构)和 Series(一维数据结构),使得数据操作、清洗、转换、合并、重塑、切片、选择、过滤等任务变得简单直观。Pandas 还支持与 SQL 一样的数据操作方式,以及强大的时间序列功能。

  3. Matplotlib: Matplotlib 是一个广泛使用的绘图库,用于创建静态、动态、交互式的图表。它为 Python 提供了一套全面的图形库,能够生成多种硬拷贝格式和跨平台的交互式环境下的图形。Matplotlib 非常灵活,用户可以通过简单的命令创建基本图表,也可以完全自定义图表的每个细节,以生成复杂的可视化结果。

这三个库相互配合,使得 Python 成为了数据分析、数据处理和数据可视化领域的强大工具。本文我先为大家详细介绍以numpy。另外两个库我也会在系列后续专栏中进行讲解。

NumPy

NumPy(Numerical Python)是Python的一种开源的数值计算扩展。提供多维数组对象,这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(如使用二层前的套列表表示二维数组)结构要高效的多,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库,包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等等。

numpy.ndarray 是 NumPy 库中的核心数据结构,代表一个多维数组。numpy.ndarray 类型是同构(即所有元素是相同的数据类型)的,支持大量的数学运算操作。numpy.ndarray 提供了对大数据集进行高效计算的能力,是科学计算、数据分析等领域中不可或缺的工具。ndarray数组在执行相同的数组操作时,其运行速度要比python自带的数组快得多,这也是我们使用numpy的主要原因,本文主要介绍也都是围绕ndarray的各种操作展开。

在进行操作之前,我们首先应该导入相关的依赖库,这些库都在anaconda中进行了集成,因此无需手动下载。

py 复制代码
# 导入数据分析 "三剑客"并为它们起好别名方便使用,这些别名是官方认可的用法
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

创建ndarray

创建ndarray 数组的方式有很多种,这里介绍我常用的几种:

np.array()

使用np.array()方法,可以将python中的list或tuple对象转换为ndarray类型。

注意:numpy默认ndarray的所有元素的类型是相同的。如果传进来的列表中包含不同的类型,则自动转变为同一类型(隐式类型转换),优先级:str>float>int

【示例】把python的列表(list)转换为numpy.ndarray类型

py 复制代码
# 使用np.array()创建ndarray
list1 = [1,2,3,4]
n = np.array(list1)
display(n)
print(type(n))

# 输出:
# array([1, 2, 3, 4])
# <class 'numpy.ndarray'>

【示例】把python的元组(tuple)转换为numpy.ndarray类型

Python 复制代码
# 使用np.array()将元组转换为ndarray
tuple1 = (1,2,3,4)
n = np.array(tuple1)
display(n)
print(type(n))

# 输出:
# array([1, 2, 3, 4])
# <class 'numpy.ndarray'>

常见数组创建

在涉及到数组操作的时候,有时候我们需要一些特殊的数组,如随机数组、零数组等,numpy为我们提供了以下常见数组的创建方法:

np.ones
py 复制代码
np.ones(shape, dtype=None, order='C')

创建一个所有元素都为1的多维数组

参数说明:

  • shape : 形状

  • dtype=None: 元素类型

  • order : {'C','F'},可选参数,默认值:C 是否在内存中以行主(C-风格)或列主(Fortran-风格)顺序存储多维数据, 一般默认即可

    python 复制代码
    # 创建一个所有元素都为1的多维数组
    n = np.ones(5)
    n
    # 输出:
    # array([1., 1., 1., 1., 1.])
    
    n = np.ones((3, 4), dtype=np.int)  # 整数,3行4列
    n
    # 输出:
    # array([[1, 1, 1, 1],
    #        [1, 1, 1, 1],
    #        [1, 1, 1, 1]])
np.zeros
py 复制代码
np.zeros(shape, dtype=float, order='C')

创建一个所有元素都为0的多维数组

参数说明:

  • shape : 形状

  • dtype=float: 数据类型,默认为浮点型

    python 复制代码
    # 创建一个所有元素都为0的多维数组
    n = np.zeros((5,5), dtype=np.int)
    n
    # 输出
    # array([[0, 0, 0, 0, 0],
    #       [0, 0, 0, 0, 0],
    #       [0, 0, 0, 0, 0],
    #       [0, 0, 0, 0, 0],
    #       [0, 0, 0, 0, 0]])
np.full
py 复制代码
np.full(shape, fill_value, dtype=None, order='C')

创建一个所有元素都为指定元素的多维数组

参数说明:

  • shape: 形状

  • fill_value: 填充值

  • dtype=None: 元素类型

    python 复制代码
    # 创建一个所有元素都为8的多维数组
    n = np.full((2,3,4), 8)
    n
    # 输出
    # array([[8, 8, 8, 8, 8],
    #       [8, 8, 8, 8, 8],
    #       [8, 8, 8, 8, 8],
    #       [8, 8, 8, 8, 8],
    #       [8, 8, 8, 8, 8]])
np.eye
py 复制代码
np.eye(N, M=None, k=0, dtype=float)

对角线为1其他的位置为0的二维数组,和数据结构中的单位矩阵类似

参数说明:

  • N: 行数

  • M: 列数, 默认为None,表示和行数一样

  • k=0: 对角线向右偏移0个位置

  • dtype=float: 数据类型,默认为浮点型

    python 复制代码
    # 对角线为1其他的位置为0
    n = np.eye(6, 6, dtype=int)
    n
    # 输出
    # array([[1, 0, 0, 0, 0, 0],
    #       [0, 1, 0, 0, 0, 0],
    #       [0, 0, 1, 0, 0, 0],
    #       [0, 0, 0, 1, 0, 0],
    #       [0, 0, 0, 0, 1, 0],
    #       [0, 0, 0, 0, 0, 1]])
    
    # 右偏移2个位置
    n = np.eye(6,6, k=2, dtype=int)
    # 左偏移2个位置
    n = np.eye(6,6, k=-2, dtype=int)
    n
    # 输出
    # array([[0, 0, 0, 0, 0, 0],
    #       [0, 0, 0, 0, 0, 0],
    #       [1, 0, 0, 0, 0, 0],
    #       [0, 1, 0, 0, 0, 0],
    #       [0, 0, 1, 0, 0, 0],
    #       [0, 0, 0, 1, 0, 0]])
np.linspace
py 复制代码
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

创建一个等差数列

参数说明:

  • start: 起始值

  • stop: 结束值

  • num=50: 在起始值和结束值之间有几个数

  • endpoint=True: 是否包含结束值

  • retstep=False: 是否返回等差值(步长)

  • dtype=None: 元素类型

    python 复制代码
    # 创建一个等差数列
    n = np.linspace(0, 100, dtype=np.int)
    n
    # 输出
    # array([  0,   2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24,
    #        26,  28,  30,  32,  34,  36,  38,  40,  42,  44,  46,  48,  51,
    #        53,  55,  57,  59,  61,  63,  65,  67,  69,  71,  73,  75,  77,
    #        79,  81,  83,  85,  87,  89,  91,  93,  95,  97, 100])
    
    # num=20
    n = np.linspace(0, 100, num=20, dtype=np.int)
    n
    # 输出
    # array([  0,   5,  10,  15,  21,  26,  31,  36,  42,  47,  52,  57,  63,
    #         68,  73,  78,  84,  89,  94, 100])
    
    # endpoint=False
    n = np.linspace(0, 100, 50, dtype=np.int, endpoint=False)
    n
    # 输出
    # array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
    #       34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66,
    #       68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98])
    
    # 显示差值: retstep=True
    n = np.linspace(0, 100, num=51, dtype=np.int, retstep=True)
    n
    # 输出
    # (array([  0,   2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24,
    #         26,  28,  30,  32,  34,  36,  38,  40,  42,  44,  46,  48,  50,
    #         52,  54,  56,  58,  60,  62,  64,  66,  68,  70,  72,  74,  76,
    #         78,  80,  82,  84,  86,  88,  90,  92,  94,  96,  98, 100]),
    #   2.0)
np.arange
py 复制代码
np.arange([start, ]stop, [step, ]dtype=None)

创建一个数值范围的数组;和Python中range功能类似

参数说明:

  • start : 开始值(可选)

  • stop: 结束值(不包含)

  • step: 步长(可选)

  • dtype=None: 元素类型

    python 复制代码
    n = np.arange(10)
    n
    # 输出
    # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    n = np.arange(2, 10)
    n
    # 输出
    # array([2, 3, 4, 5, 6, 7, 8, 9])
    
    n = np.arange(2,10,2)
    n
    # 输出
    # array([2, 4, 6, 8])
np.random.randint
py 复制代码
np.random.randint(low, high=None, size=None, dtype='l')
  • 创建一个随机整数的多维数组

参数说明:

  • low : 最小值

  • high=None: 最大值

    • high=None时,生成的数值在[0, low)区间内
    • 如果使用high这个值,则生成的数值在[low, high)区间
  • size=None: 数组形状, 默认只输出一个随机值

  • dtype=None: 元素类型

    python 复制代码
    # 随机整数
    n = np.random.randint(3)
    n
    # 输出
    # 范围[0,3)的随机数
    
    # 随机整数范围: [3,10)
    n = np.random.randint(3,10)
    n
    
    # 随机取多维数组: 一维
    n = np.random.randint(0, 10, size=6)
    n
    
    # 随机取多维数组: 二维
    n = np.random.randint(0, 10, size=(5,6))
    n
    
    # 随机取多维数组: 三维
    n = np.random.randint(0, 256, size=(5,6,3))
    n
np.random.randn
py 复制代码
np.random.randn(d0, d1, ..., dn)

创建一个服从标准正态分布的多维数组

标准正态分布又称为u分布,是以0为均数、以1为标准差的正态分布,记为N(0,1)

标准正态分布, 在0左右出现的概率最大, 越远离出现的概率越低, 如下图

参数说明:

  • dn : 第n个维度的数值

    python 复制代码
    # 服从标准正态分布的1个随机数
    n = np.random.randn()
    n
    # 输出:
    # 1.2504214947360053
    
    n = np.random.randn(5)
    n
    # 输出:
    # array([-0.7128816 , -0.59774126, -0.37593764,  1.40430347,  1.14993985])
    
    n = np.random.randn(3, 4)
    n
    # 输出
    # array([[ 0.43916101, -1.06884447, -0.57431013, -0.19757668],
    #       [-0.73136802,  0.23505987,  0.72660045, -1.17924178],
    #       [-1.69825721, -1.22735202,  1.00713952,  1.36712314]])
np.random.normal
py 复制代码
np.random.normal(loc=0.0, scale=1.0, size=None)
  • 创建一个服从正态分布的多维数组

参数说明:

  • loc=0.0: 均值, 对应着正态分布的中心

  • scale: 标准差, 对应分布的宽度,scale越大,正态分布的曲线越矮胖,scale越小,曲线越高瘦

  • size=None: 数组形状

    python 复制代码
    # 正态分布
    n = np.random.normal(170, 5, size=(3,4))
    n
    
    # 输出
    # array([[179.10438995, 165.18684991, 171.63073659, 171.2585855 ],
    #       [166.93875293, 166.55466363, 170.58427719, 173.20074627],
    #       [168.78374382, 168.82095611, 163.30749889, 168.24241435]])
np.random.random
py 复制代码
np.random.random(size=None)

创建一个元素为0~1(左闭右开)的随机数的多维数组

参数说明:

  • size=None: 数组形状

    python 复制代码
    # 生成0~1的随机数
    n = np.random.random(size=(3,4))
    n
    
    # 输出
    # array([[0.34301757, 0.02670685, 0.73963601, 0.98623872],
    #       [0.70800093, 0.819704  , 0.31882191, 0.47946659],
    #       [0.17492185, 0.19123102, 0.58646357, 0.6245818 ]])
np.random.rand
np.random.rand(d0, d1, ..., dn)

创建一个元素为0~1(左闭右开)的随机数的多维数组;和np.random.random功能类似, 掌握其中一个即可,在别的代码中见到之后要认识

ndarray的属性

ndarray对象有许多属性,查看这些属性,可以帮助我们更加全面地理解ndarray的性质,以下是其中一些关键属性:

python 复制代码
# 使用随机数组进行测试
n = np.random.randint(0, 256, size=(20,40,3))
n

维度

ndim:维度

python 复制代码
cat.ndim  # 维度
# 输出
#   3

形状

shape:形状(各维度的长度)

python 复制代码
cat.shape  # 形状
# 输出
#   (20,40,3)

长度

size:总长度

python 复制代码
cat.size  # 总长度
# 输出
#   2400

元素类型

dtype:元素类型

python 复制代码
cat.dtype  # 元素类型  
# 输出
#   dtype('int64')

ndarray的索引和切片

在NumPy的ndarray中,索引和切片功能非常强大,允许你灵活地访问和操作数组中的数据。ndarray的索引和切片操作和python的list类型的索引和切片类似,如果你使用list类型的索引和切片操作很熟练,以下内容会更好理解。

python 复制代码
# 列表
l = [1,2,3,4,5,6]
l[3]
# 输出
#  4

# numpy数组(ndarray类型)
n = np.array(l)
n[3]
# 输出
#  4

# 二维数组
n = np.random.randint(0,10, size=(4,5))
n
# array([[1, 2, 5, 1, 5],
#       [5, 5, 6, 9, 8],
#       [3, 4, 2, 2, 0],
#       [4, 4, 8, 4, 3]])

# 使用索引找到元素3
n[3][4]
n[-1][-1]
# 简写
n[3,4]
n[-1,-1]

根据索引修改数据

python 复制代码
# 定位到指定元素,直接修改
n[2,2] = 6666

n = np.zeros((6,6), dtype=int)
n
# 输出
# array([[0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0]])

# 修改1行
n[0] = 1
n
# 输出
# array([[1, 1, 1, 1, 1, 1],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0]])

# 使用嵌套list修改多行
n[[0,3,-1]] = 2
n
# 输出
# array([[2, 2, 2, 2, 2, 2],
#       [0, 0, 0, 0, 0, 0],
#       [0, 0, 0, 0, 0, 0],
#       [2, 2, 2, 2, 2, 2],
#       [0, 0, 0, 0, 0, 0],
#       [2, 2, 2, 2, 2, 2]])
python 复制代码
# 列表切片
l = [1,2,3,4,5,6]
l[::-1]
# 输出
# [6, 5, 4, 3, 2, 1]

# 一维数组
n = np.arange(10)
n
# 输出
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

n[::2]
# 输出
# array([0, 2, 4, 6, 8])

n[::-1]
# 输出
# array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

# 多维数组
n = np.random.randint(0,100, size=(5,6))
n
# 输出
# array([[94, 45, 60, 71, 70, 88],
#       [43, 16, 39, 70, 14,  4],
#       [59, 12, 84, 38, 96, 88],
#       [80,  9, 72, 95, 69, 91],
#       [44, 84,  5, 47, 92, 31]])

#  行 翻转
n[::-1]

# 列 翻转 (第二个维度)
n[:, ::-1]

ndarray的变形操作

使用np.reshape()函数对ndarray数组进行变形, 注意参数是tuple

python 复制代码
n = np.arange(1, 21)
n
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])

n.shape
# (20,)

# 变成2维
n2 = np.reshape(n, (4,5))
n2
# array([[ 1,  2,  3,  4,  5],
#       [ 6,  7,  8,  9, 10],
#       [11, 12, 13, 14, 15],
#       [16, 17, 18, 19, 20]])

n2.shape
# (4, 5)

n2.reshape((20,))  # 变成一维
n2.reshape((-1,))  # 变成一维

# 改变cat的形状
cat.shape
# (456, 730, 3)

#  -1 表示行会自动分配,列数是6
cat2 = cat.reshape((-1, 6))
cat2.shape
# (166440, 6)

#  -1 表示列会自动分配,行数是6
cat2 = cat.reshape((6,-1))
cat2.shape
# (6, 166440)

ndarray的合并与拆分操作

合并ndarray

使用np.concatenate()函数实现多个ndarray的合并,这个操作也被叫做级联,但我觉得级联定义不明确,所以不用这种说法。

python 复制代码
n1 = np.random.randint(0,100, size=(4,5))
n2 = np.random.randint(0,100, size=(4,5))
display(n1, n2)
# array([[48, 89, 82, 88, 55],
#       [63, 80, 77, 27, 51],
#       [11, 77, 90, 23, 71],
#       [ 4, 11, 19, 84, 57]])
# 
#array([[86, 26, 71, 62, 46],
#       [75, 43, 84, 87, 99],
#       [34, 33, 58, 56, 29],
#       [56, 32, 53, 43,  5]])

# 上下合并
np.concatenate((n1, n2))
np.concatenate((n1, n2), axis=0)  # axis=0表示行,第一个维度
# array([[48, 89, 82, 88, 55],
#       [63, 80, 77, 27, 51],
#       [11, 77, 90, 23, 71],
#       [ 4, 11, 19, 84, 57],
#       [86, 26, 71, 62, 46],
#       [75, 43, 84, 87, 99],
#       [34, 33, 58, 56, 29],
#       [56, 32, 53, 43,  5]])

# 左右合并
np.concatenate((n1, n2), axis=1)  # axis=1表示列,第二个维度
# array([[48, 89, 82, 88, 55, 86, 26, 71, 62, 46],
#       [63, 80, 77, 27, 51, 75, 43, 84, 87, 99],
#       [11, 77, 90, 23, 71, 34, 33, 58, 56, 29],
#       [ 4, 11, 19, 84, 57, 56, 32, 53, 43,  5]])

ndarray还具有专门的水平和垂直合并方法:np.hstack()与np.vstack(),使用这两个方法就不需要指定合并维度了,更加直观

python 复制代码
# 左右合并
np.hstack((n1, n2)) 
# array([[48, 89, 82, 88, 55, 86, 26, 71, 62, 46],
#       [63, 80, 77, 27, 51, 75, 43, 84, 87, 99],
#       [11, 77, 90, 23, 71, 34, 33, 58, 56, 29],
#       [ 4, 11, 19, 84, 57, 56, 32, 53, 43,  5]])

# 上下合并
np.vstack((n1, n2)) 
# array([[48, 89, 82, 88, 55],
#       [63, 80, 77, 27, 51],
#       [11, 77, 90, 23, 71],
#       [ 4, 11, 19, 84, 57],
#       [86, 26, 71, 62, 46],
#       [75, 43, 84, 87, 99],
#       [34, 33, 58, 56, 29],
#       [56, 32, 53, 43,  5]])

拆分ndarray

拆分和合并类似,有三个方法:np.split()、np.vsplit()和np.hsplit(),用法和合并方法一样,np.split()需要指定拆分维度,np.vsplit()和np.hsplit()为垂直拆分和水平拆分

python 复制代码
n = np.random.randint(0, 100, size=(6,4))
n
# array([[ 3, 90, 62, 89],
#       [75,  7, 10, 76],
#       [77, 94, 88, 59],
#       [78, 66, 81, 83],
#       [18, 88, 40, 81],
#       [ 2, 38, 26, 21]])

# 垂直方向,平均切成3份
np.vsplit(n, 3)
# [array([[ 3, 90, 62, 89],
#        [75,  7, 10, 76]]),
# array([[77, 94, 88, 59],
#        [78, 66, 81, 83]]),
# array([[18, 88, 40, 81],
#        [ 2, 38, 26, 21]])]

# 如果是数组
np.vsplit(n, (1,2,4))
# [array([[ 3, 90, 62, 89]]),
#  array([[75,  7, 10, 76]]),
#  array([[77, 94, 88, 59],
#        [78, 66, 81, 83]]),
#  array([[18, 88, 40, 81],
#        [ 2, 38, 26, 21]])]

# 水平方向
np.hsplit(n, 2)
# [array([[97, 86],
#        [16, 70],
#        [26, 95],
#        [ 6, 83],
#        [97, 43],
#        [96, 57]]),
# array([[88, 69],
#        [60,  7],
#        [32, 82],
#        [24, 86],
#        [62, 23],
#        [43, 19]])]

# 通过axis来按照指定维度拆分
np.split(n, 2, axis=1)
# [array([[97, 86],
#        [16, 70],
#        [26, 95],
#        [ 6, 83],
#        [97, 43],
#        [96, 57]]),
# array([[88, 69],
#        [60,  7],
#        [32, 82],
#        [24, 86],
#        [62, 23],
#        [43, 19]])]

ndarray的复制

使用copy()方法进行ndarry对象的拷贝,要注意和直接使用等号进行复制之间的区别。

python 复制代码
# 赋值: 不使用copy
n1 = np.arange(10)
n2 = n1
n1[0] = 100
display(n1, n2)
# array([100,   1,   2,   3,   4,   5,   6,   7,   8,   9])
# array([100,   1,   2,   3,   4,   5,   6,   7,   8,   9])

# 拷贝: copy
n1 = np.arange(10)
n2 = n1.copy()
n1[0] = 100
display(n1, n2)
# array([100,   1,   2,   3,   4,   5,   6,   7,   8,   9])
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

ndarray的转置

transpose方法(或其快捷方式.T)用于交换数组的轴,即将行变成列,列变成行,主要应用于二维数组时效果最为直观,对于高维数组则是轴的重新排序。

默认情况下,transpose()不带参数时,等同于.T,会按最后一个轴到第一个轴的逆序交换轴。你也可以显式指定轴的顺序,如arr.transpose(axis_order)

主要在需要改变数据布局以适应不同的计算或可视化需求时使用,比如将图像数据从宽度x高度转换为高度x宽度。

python 复制代码
# 转置
n = np.random.randint(0, 10, size=(3, 4)) 
n.T  

# transpose改变数组维度
n = np.random.randint(0, 10, size=(3, 4, 5)) # shape(3, 4, 5)
np.transpose(n, axes=(2,0,1))  

ndarray的聚合操作

聚合操作(Aggregation Operations)是指在数据分析、数据库查询或编程中,将一组数据简化为一个代表性的值或少量值的过程。这些操作通常用于总结数据集的特征、发现模式或提取重要统计信息。以下是在不同上下文中常见的几种聚合操作:

python 复制代码
# 求和np.sum
# 一维
n = np.arange(10)
np.sum(n)
# 45

# 二维
n = np.random.randint(0,10, size=(3,4))
n
# array([[7, 9, 1, 6],
#       [6, 4, 7, 1],
#       [7, 6, 6, 0]])

np.sum(n)
# 60

# axis 轴的意思,表示第几个维度,从0开始, 在二维中0表示行,1表示列
np.sum(n, axis=0)
# array([20, 19, 14,  7])

np.sum(n, axis=1)
# array([23, 18, 19])


n = np.random.randint(0,10, size=(3,4))
n
# array([[7, 6, 1, 1],
#       [2, 9, 3, 9],
#       [2, 7, 9, 5]])

# 最大值
np.max(n) 
# 最小值
np.min(n)  

# 平均值
np.mean(n)  # 5.166666666666667
np.average(n)  # 5.166666666666667
# 中位数
np.median(n) 

# 变成一维
n = n.reshape((-1,))
display(n)
# array([7, 6, 1, 1, 2, 9, 3, 9, 2, 7, 9, 5])

# 最小数下标
np.argmin(n)   # 2
# 最大数下标
np.argmax(n)   # 5

np.std(n)  # 标准差 3.0402393911591163
np.var(n)  # 方差  9.243055555555555

# 次方
n = np.array([1,2,3])
# n**3
np.power(n,3)

# np.argwhere: 根据条件查找
n = np.random.randint(0,5, size=10)
display(n)
# array([0, 3, 3, 0, 4, 2, 3, 3, 1, 4])
display(np.argmax(n))  # 只能找到第一个最大数下标
np.argwhere(n==np.max(n))  # 找到所有最大数的下标
# array([[4],
#        [9]])

np.sum 和 np.nansum 的区别 nan: not a number

py 复制代码
n = np.array([1,2,3,np.nan])
n
# array([ 1.,  2.,  3., nan])

np.sum(n)  # nan
np.nansum(n)  # 6.0  计算nan以外的元素

【示例】创建一个长度为10的随机数组并将最大值替换为0

python 复制代码
n = np.random.randint(0,10, size=10)
display(n)
# array([9, 0, 6, 8, 8, 8, 7, 5, 6, 8])

max1 = np.max(n)
max_indexs = np.argwhere(n==max1).reshape((-1,))
display(max_indexs)
# array([0])

n[max_indexs] = 0
n
# array([0, 0, 6, 8, 8, 8, 7, 5, 6, 8])

ndarray的矩阵操作

基本矩阵操作

算术运算符:

  • 加减乘除

    python 复制代码
    n = np.random.randint(0,10, size=(4,5))
    n
    # array([[8, 0, 8, 2, 4],
    #       [7, 6, 5, 1, 2],
    #       [1, 4, 7, 6, 0],
    #       [4, 8, 5, 7, 7]])
    
    n + 1  # 加
    n - 1  # 减
    n * 2  # 乘
    n / 2  # 除
    n // 2  # 整除
    n % 2  # 余数
    
    n2 = np.random.randint(0,10, size=(4,5))
    display(n, n2)
    # array([[8, 0, 8, 2, 4],
    #       [7, 6, 5, 1, 2],
    #       [1, 4, 7, 6, 0],
    #       [4, 8, 5, 7, 7]])
    # array([[5, 0, 0, 6, 4],
    #       [6, 5, 1, 7, 0],
    #       [8, 0, 6, 6, 3],
    #       [4, 3, 1, 0, 3]])
    
    n + n2
    # array([[13,  0,  8,  8,  8],
    #       [13, 11,  6,  8,  2],
    #       [ 9,  4, 13, 12,  3],
    #       [ 8, 11,  6,  7, 10]])

线性代数中常用矩阵操作

  • 矩阵与矩阵的乘积

    python 复制代码
    n1 = np.random.randint(0, 10, size=(2,3))
    n2 = np.random.randint(0, 10, size=(3,4))
    display(n1, n2)
    # array([[1, 9, 7],
    #       [9, 1, 1]])
    # array([[4, 6, 9, 9],
    #       [8, 5, 8, 3],
    #       [0, 9, 4, 1]])
    
    # 矩阵积
    np.dot(n1, n2)
    n1 @ n2
    # array([[ 76, 114, 109,  43],
    #       [ 44,  68,  93,  85]])
    """
    [3*5+3*4+7*5, 3*3+3*1+7*5, 3*6+3*3+7*9, 3*4+3*0+7*7] 
    [6*5+9*4+3*5, 6*3+9*1+3*5, 6*6+9*3+3*9, 6*4+9*0+3*7]
    """		
  • 线性代数其他操作

    python 复制代码
    # 线性代数常用
    n = np.array([[1, 2, 3],
                  [2, 5, 4],
                  [4, 5, 8]]) 
    np.linalg.inv(n) # 逆矩阵
    np.linalg.det(n) # 计算矩阵行列式
    
    # 矩阵的秩(满秩矩阵或奇异矩阵)
    np.linalg.matrix_rank(n)

其他数学函数

  • abs、sqrt、square、exp、log、sin、cos、tan、round、ceil、floor、cumsum

    python 复制代码
    n = np.array([1, 4, 8, 9, 16, 25])
    
    np.abs(n) # 绝对值
    np.sqrt(n) # 开平方
    np.square(n) # 平方
    np.exp(n) # 指数
    np.log(n) # 自然对数,以e为底的对数
    np.log(np.e)  # 自然对数,以e为底的对数
    np.log(1)  # 0
    np.log2(n) # 对数
    np.log10(n) # 10为底的对数  常用对数
    
    np.sin(n) # 正弦
    np.cos(n) # 余弦
    np.tan(n) # 正切
    np.round(n) # 四舍五入
    np.ceil(n) # 向上取整
    np.floor(n) # 向下取整
    
    np.cumsum(n) # 计算累加和

广播机制【重要】

ndarray广播机制的两条规则

  • 规则一:为缺失的维度补维度
  • 规则二:缺失元素用已有值填充
python 复制代码
m = np.ones((2,3), dtype=int)
a = np.arange(3)
display(m, a)
# array([[1, 1, 1],
#        [1, 1, 1]])
# 
# array([0, 1, 2])

m + a
# array([[1, 2, 3],
#        [1, 2, 3]])

a = np.arange(3).reshape((3,1))
b = np.arange(3)
display(a, b)
# array([[0],
#        [1],
#        [2]])
# array([0, 1, 2])

a + b
# array([[0, 1, 2],
#        [1, 2, 3],
#        [2, 3, 4]])

a = np.ones((4,1), dtype=int)
b = np.arange(4)
display(a, b)
# array([[1],
#        [1],
#        [1],
#        [1]])
# array([0, 1, 2, 3])

a + b
# array([[1, 2, 3, 4],
#        [1, 2, 3, 4],
#        [1, 2, 3, 4],
#        [1, 2, 3, 4]])

ndarray的排序

快速排序

np.sort()与ndarray.sort()都可以,但有区别:

  • np.sort()不改变输入
  • ndarray.sort()本地处理,不占用空间,但改变输入
python 复制代码
n1 = np.random.randint(0, 10, size=6)
n1
# array([3, 7, 8, 4, 7, 7])

np.sort(n1)
# array([3, 4, 7, 7, 7, 8])
n1   
# array([3, 7, 8, 4, 7, 7])


n2 = np.random.randint(0, 10, size=6)
n2
# array([7, 7, 6, 0, 3, 9])
n2.sort()
n2
# array([0, 3, 6, 7, 7, 9])

ndarray文件操作

保存数组

  • save : 保存ndarray到一个npy文件
  • savez : 将多个array保存到一个npz文件中
python 复制代码
x = np.arange(0, 10)
y = np.arange(10,20)

# save
np.save("x",x)

# savez
np.savez("arr.npz",xarr = x,yarr=y)

读取数组

python 复制代码
# 读取npy文件
np.load('x_arr.npy') 

# 读取npz文件
np.load('arr.npz')['yarr']

csv、txt文件的读写操作

python 复制代码
n = np.random.randint(0, 10,size = (3,4))

# 储存数组到txt或csv, delimiter为分隔符
np.savetxt("arr.csv", n, delimiter=',') # 文件后缀是txt也是一样的

# 读取txt或csv
np.loadtxt("arr.csv", delimiter=',', dtype=np.int32)
相关推荐
Leo.yuan14 小时前
数据量大Excel卡顿严重?选对报表工具提高10倍效率
数据库·数据分析·数据可视化·powerbi
小锋学长生活大爆炸18 小时前
【教程】Cupy、Numpy、Torch互相转换
pytorch·numpy·cupy
海边散步的蜗牛19 小时前
学术论文写作丨机器学习与深度学习
人工智能·深度学习·机器学习·chatgpt·数据分析·ai写作
数模竞赛Paid answer21 小时前
2023年MathorCup数学建模A题量子计算机在信用评分卡组合优化中的应用解题全过程文档加程序
数学建模·数据分析·mathorcup
爱睡觉的咋1 天前
GNN入门案例——KarateClub结点分类
人工智能·分类·数据挖掘·图神经网络
康谋自动驾驶1 天前
康谋分享 | 确保AD/ADAS系统的安全:避免数据泛滥的关键
数据分析·自动驾驶·汽车
封步宇AIGC1 天前
量化交易系统开发-实时行情自动化交易-3.4.1.2.A股交易数据
人工智能·python·机器学习·数据挖掘
m0_523674211 天前
技术前沿:从强化学习到Prompt Engineering,业务流程管理的创新之路
人工智能·深度学习·目标检测·机器学习·语言模型·自然语言处理·数据挖掘
封步宇AIGC1 天前
量化交易系统开发-实时行情自动化交易-3.4.1.6.A股宏观经济数据
人工智能·python·机器学习·数据挖掘
幸运小新1 天前
数据分析-Excel基础操作
数据分析