【数据分析“三剑客”】—— 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中进行了集成,因此无需手动下载。

# 导入数据分析 “三剑客”并为它们起好别名方便使用,这些别名是官方认可的用法
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类型

# 使用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类型

# 使用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
np.ones(shape, dtype=None, order='C')

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

参数说明:

  • shape : 形状

  • dtype=None: 元素类型

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

    # 创建一个所有元素都为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
np.zeros(shape, dtype=float, order='C')

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

参数说明:

  • shape : 形状

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

    # 创建一个所有元素都为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
np.full(shape, fill_value, dtype=None, order='C')

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

参数说明:

  • shape: 形状

  • fill_value: 填充值

  • dtype=None: 元素类型

    # 创建一个所有元素都为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
np.eye(N, M=None, k=0, dtype=float)

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

参数说明:

  • N: 行数

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

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

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

    # 对角线为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
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

创建一个等差数列

参数说明:

  • start: 起始值

  • stop: 结束值

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

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

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

  • dtype=None: 元素类型

    # 创建一个等差数列
    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
np.arange([start, ]stop, [step, ]dtype=None)

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

参数说明:

  • start : 开始值(可选)

  • stop: 结束值(不包含)

  • step: 步长(可选)

  • dtype=None: 元素类型

    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
np.random.randint(low, high=None, size=None, dtype='l')
  • 创建一个随机整数的多维数组

参数说明:

  • low : 最小值

  • high=None: 最大值

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

  • dtype=None: 元素类型

    # 随机整数
    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
np.random.randn(d0, d1, ..., dn)

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

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

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

参数说明:

  • dn : 第n个维度的数值

    # 服从标准正态分布的1个随机数
    n = np.random.randn()
    n
    # 输出:
    # 1.2504214947360053n = 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
np.random.normal(loc=0.0, scale=1.0, size=None)
  • 创建一个服从正态分布的多维数组

参数说明:

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

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

  • size=None: 数组形状

    # 正态分布
    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
np.random.random(size=None)

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

参数说明:

  • size=None: 数组形状

    # 生成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的性质,以下是其中一些关键属性:

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

维度

ndim:维度

cat.ndim  # 维度
# 输出
#   3

形状

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

cat.shape  # 形状
# 输出
#   (20,40,3)

长度

size:总长度

cat.size  # 总长度
# 输出
#   2400

元素类型

dtype:元素类型

cat.dtype  # 元素类型  
# 输出
#   dtype('int64')

ndarray的索引和切片

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

# 列表
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]

根据索引修改数据

# 定位到指定元素,直接修改
n[2,2] = 6666n = 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]])
# 列表切片
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

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的合并,这个操作也被叫做级联,但我觉得级联定义不明确,所以不用这种说法。

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(),使用这两个方法就不需要指定合并维度了,更加直观

# 左右合并
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()为垂直拆分和水平拆分

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对象的拷贝,要注意和直接使用等号进行复制之间的区别。

# 赋值: 不使用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宽度。

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

# 求和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)   # 5np.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

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

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的矩阵操作

基本矩阵操作

算术运算符:

  • 加减乘除

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

线性代数中常用矩阵操作

  • 矩阵与矩阵的乘积

    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]
    """		
    
  • 线性代数其他操作

    # 线性代数常用
    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

    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广播机制的两条规则

  • 规则一:为缺失的维度补维度
  • 规则二:缺失元素用已有值填充
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()本地处理,不占用空间,但改变输入
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文件中
x = np.arange(0, 10)
y = np.arange(10,20)# save
np.save("x",x)# savez
np.savez("arr.npz",xarr = x,yarr=y)

读取数组

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

csv、txt文件的读写操作

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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/37892.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RClone挂载有阿里云的AList

转自个人博客&#xff1a;https://www.jjy2023.cn/2024/05/23/rclone%e6%8c%82%e8%bd%bd%e6%9c%89%e9%98%bf%e9%87%8c%e4%ba%91%e7%9a%84alist-md/ RClone挂载一般的AList可以直接使用mount命令&#xff0c;但是阿里云需要使用指定头部Referer:https://www.aliyundrive.com/ &a…

51单片机第11步_在C语言中插入汇编语言

本章重点介绍如何在C语言中插入汇编语言。要不是有记录&#xff0c;真不知道怎么搞。 /* 你在 Project Workspace窗口中,将光标移到DELAY.c处,点下鼠标右键,选择"Options for file DELAY.c", 点击右边的"Generate Assembler SRC File"和“Assemble SRC …

【PL理论深化】(12) Ocaml 语言:高阶函数 | map 函数 | filter 函数 | fold 函数

&#x1f4ac; 写在前面&#xff1a;在函数式编程中&#xff0c;除了递归函数外&#xff0c;还经常使用高阶函数。高阶函数是指接收其他函数作为参数或返回另一个函数的函数。高阶函数通过抽象编程模式以实现重用&#xff0c;使程序可以在更高层次上进行编写。让我们重点看看常…

K8S基础简介

用于自动部署&#xff0c;扩展和管理容器化应用程序的开源系统。 功能&#xff1a; 服务发现和负载均衡&#xff1b; 存储编排&#xff1b; 自动部署和回滚&#xff1b; 自动二进制打包&#xff1b; 自我修复&#xff1b; 密钥与配置管理&#xff1b; 1. K8S组件 主从方式架…

A - ABA and BAB-AtCoder Regular Contest 180

A - ABA and BAB 一、分析 这道题要计算出ABA和BAB组合出的字符串的变化情况并对MOD取模。 首先想到子串中出现ABAB和BABA这两种情况的处理是一样的&#xff0c;他们的变换只会产出两种变化&#xff0c;如ABAB>ABAB/AB&#xff1b;只会变成这两种情况&#xff0c;那么将长…

$nextTick

一、词义简介&#xff1a; next下一次 Tick轮询 二、应用场景&#xff1a; 当改变数据后&#xff0c;要基于更新后的新DOM进行某些操作时&#xff0c;要在nextTick所指定的回调中执行 三、原理&#xff1a; n e x t T i c k 下一次轮询的时候再执行&#xff0c; v u e 并不是说…

socket编程常见操作

1、连接的建立 分为两种&#xff1a;服务端处理接收客户端的连接&#xff1b;服务端作为客户端连接第三方服务 //作为服务端 int listenfd socket(AF_INET, SOCK_STREAM, 0); bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) listen(listenfd, 10); //…

SARscape打开Sentinel1A SAR SLC产品(CSDB_20240630)

1.打开envi&#xff0c;在右侧工具包栏输入“sentinel-1”&#xff0c;并点击打开工具包。 2. 弹出文件导入界面&#xff0c;点击右侧Browse按钮。 3. 选在本地下载好的Sentinel1产品&#xff0c;文件路径最好全是英文&#xff0c;不要出现中文和特殊字符。 4 点击下方“Exec”…

python项目实战——人生重开模拟器

文章目录 1.菜单栏的编写2.玩家确定颜值、体质、智力、家境3.生成性别4.设定角色出生点5.各个年龄段的变化5.1 幼年阶段5.2 青年阶段5.3中年阶段5.4 晚年阶段 6.整体代码 人生重开模拟器是一款文字类小游戏. 玩家可根据提示输入角色的初始属性之后, 就可以开启不同的人生经历. …

BLACKBOX.AI:解锁编程学习新纪元,加速开发的AI得力助手

文章目录 &#x1f4af;BLACKBOX.AI 官网&#x1f341;1 BLACKBOX.AI 工具使用教程&#x1f341;2 BLACKBOX.AI工具使用界面介绍&#x1f341;3 Chat(聊天)功能&#x1f341;4 Explore (探索)功能&#x1f48e;4.1 Terminal(终端)功能&#x1f48e;4.2 Discover(发现)功能&…

负载均衡算法

负载均衡是一种将传入的网络流量分配到多个服务器或资源上的技术&#xff0c;以确保每个服务器的负载都在可接受的范围内&#xff0c;从而提高系统的性能和可靠性。常见的负载均衡策略有很多&#xff0c;以下是一些常见的策略以及它们的优缺点&#xff1a; 1. 随机&#xff08…

ros1仿真导航机器人 hector_mapping gmapping

仅为学习记录和一些自己的思考&#xff0c;不具有参考意义。 1 hector_mapping 建图过程 &#xff08;1&#xff09;gazebo仿真 roslaunch why_simulation why_slam.launch <launch><!-- We resume the logic in empty_world.launch, changing only the name of t…

助农扶贫网站

摘要&#xff1a;随着信息科技的快速发展和互联网的普及&#xff0c;信息技术在助力农业发展、促进农村振兴以及扶贫工作中发挥着越来越重要的作用。本文基于Spring Boot框架和Vue.js前端开发技术&#xff0c;设计完成了一个助农扶贫电商网站。网站提供便捷的农产品信息发布、农…

three.js - MeshStandardMaterial(标准网格材质)- 金属贴图、粗糙贴图

金属贴图、粗糙贴图 金属贴图&#xff1a;metalnessMap 和 粗糙贴图&#xff1a;roughnessMap&#xff0c;是用于模拟物体表面属性的两种重要贴图技术&#xff0c;这两种贴图&#xff0c;通常与基于物理的渲染&#xff08;PBR&#xff09;材质&#xff08;如&#xff1a;MeshSt…

DC-DC产品设计PCB注意事项

DC-DC的电路比LDO会复杂很多&#xff0c;噪声也更大&#xff0c;布局和layout要求更高&#xff0c;layout的好坏直接影响DC-DC的性能&#xff0c;所以了解DC-DC的layout至关重要。 一、Bad Layout EMI&#xff0c;DC-DC的SW管脚上面会有较高的dv/dt&#xff0c; 比较高的dv/d…

【机器学习】机器学习、深度学习、强化学习和迁移学习简介、相互对比、区别与联系。

机器学习、深度学习、强化学习和迁移学习都是人工智能领域的子领域&#xff0c;它们之间有一定的联系和区别。下面分别对这四个概念进行解析&#xff0c;并给出相互对比、区别与联系以及应用场景案例分析。 一、概念解析 机器学习&#xff08;Machine Learning&#xff09; …

FastAPI教程II

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial Cookie参数 定义Cookie参数与定义Query和Path参数一样。 具体步骤如下&#xff1a; 导入Cookie&#xff1a;from fastapi import Cookie声明Cookie参数&#xff0c;声明Cookie参数的方式与声明Query和Path参数…

HIVE每日一题

select * from sku_info order by sku_id ; 为什么结果没有顺序排序。什么原因导致的&#xff1f;

小红书多账号管理平台哪个好用?可以快速监测多个小红书账号的数据吗?

随着品牌营销战线的不断扩展&#xff0c;小红书已经成为企业和个人品牌竞相展示的舞台。但是&#xff0c;随之而来的多账号管理问题也让众多运营者头疼不已。一个优秀的多账号管理平台&#xff0c;能让你事半功倍&#xff0c;轻松监控和分析账号数据。 如今&#xff0c;市面上出…

SiteSucker Pro for Mac:一键下载整站,轻松备份与离线浏览!

SiteSucker Pro for Mac是一款专为苹果电脑用户设计的网站下载与备份工具&#x1f578;️。它以其强大的整站下载能力和用户友好的界面&#xff0c;成为了众多Mac用户备份网站、离线浏览的得力助手&#x1f4bb;。 这款软件允许用户一键下载整个网站&#xff0c;包括所有的网页…