【数据分析“三剑客”】—— 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)
相关推荐
紫色沙9 分钟前
数据分析入门指南:从基础概念到实际应用(一)
大数据·人工智能·数据分析
李昊哲小课12 分钟前
hive4 从入门到精通
大数据·数据仓库·hive·hadoop·数据分析
数据超市1 小时前
全国现状建筑数据,选中范围即可查询下载,富含建筑物位置、层数、建筑物功能、名称地址等信息!
大数据·人工智能·信息可视化·数据挖掘·数据分析
紫色沙3 小时前
每天一个数据分析题(四百)- 一元线性回归模型
数据挖掘·数据分析·线性回归
小李很执着4 小时前
【C++】——【 STL简介】——【详细讲解】
开发语言·c++·学习·数据挖掘·mfc
破坏神在行动5 小时前
《数据仓库与数据挖掘》自测
数据仓库·数据挖掘
大数据小朋友6 小时前
【Python数据分析及环境搭建】:教程详解1(第23天)
开发语言·python·数据分析
深蓝易网10 小时前
制造企业的仓库管理如何做好数据分析?
大数据·运维·数据库·人工智能·数据挖掘·数据分析·制造
庄宝00711 小时前
【PYTORCH,TENSORFLOW环境配置,安装,自用代码】
人工智能·pytorch·python·深度学习·conda·numpy·virtualenv
方案36512 小时前
数据资产赋能企业决策:通过精准的数据分析和洞察,构建高效的数据资产解决方案,为企业提供决策支持,助力企业实现精准营销、风险管理、产品创新等目标,提升企业竞争力
大数据·数据挖掘·数据分析·数据资产管理·数据资产·数据资产化·数据资产解决方案