Python numpy视图与副本

目录
  • 1. 简单讲解
  • 2. 视图
    • 视图概念
    • 视图应用
    • 视图优点
  • 3. 副本
    • 副本概念
    • 副本应用

前言:

继上一篇对numpy 模块之ndarray一文中对 ndarray 内存结构主要分为两部分:

metdata :存放数组类型dtype、数组维度ndim、维度数量shape、维间距strides等
raw bata:存放原始数据data

metdata 中包含着关于数组相关信息,可以帮助我们在数组ndarray中快速索引和解释指定的数据

除此了对数组进行索引操作外,也会对数组的原数据进行类似与之前“拷贝”操作。

众所周知,在 Python 中大家应该对深浅拷贝有一定的印象吧,在 numpy 中则换成了“视图”与“副本”的概念了。

相信大家和我一样对此存在疑问,十万个为什么涌上心头了,“视图是什么?”,“什么是副本?”

因此,本期我们一起来学习 numpy 模块中比较新奇的概念视图与副本,Let's go~

1. 简单讲解

我们之前在学习 Python 赋值、深浅拷贝时,在代码添加中对比两个对象的地址id()是否一致。

同理,按照这样的思路,numpy 中也可以对比两个数组地址是否一样。

同时,在 numpy 数组对象ndarray 也提供许多字段,方便让我们进一步地查看数组内部的差异

ndarray.flags : 查看数组存储策略、读写权限、对象等

  • C_CONTIGUOUS (C) 行优先存储
  • F_CONTIGUOUS 列优先存储
  • OWNDATA 数据所有者
  • WRITEABLE 编写权限
  • ALIGNED 数据元素与硬件指针对齐
  • WRITEBACKIFCOPY 数组是其他数组的副本
  • UPDATEIFCOPY 已弃用

注:flags 相关属性名称可以单独调用例如 flags.writeable

  • ndarray.base : 查看数组中的元素是否来自其他数组
  • ndarray.nbytes: 查看数组中数据占用的字节数
  • getsizeof(item): 查看数组占用的内存空点

介绍完上述指标,我们来小试一下:

>>> import numpy as np
>>> a = np.array([1,2,3,4])
>>> print(a[1:3])
[2 3]
>>> print(a[[1,2]])
[2 3]
>>>

查看a[1:3] 与 a[[1,2]] 内存地址,它们俩位置不一样,a[[1,2]]意味发生了深拷贝本(副本),a[1:3] 是原数组a引用(视图)

>>> print(id(a[1:3]))
2247482965008
>>> print(id(a[[1,2]]))
2247482964928

查看ndarray.owndata 属性,发现a[1:3] 数据来自a数组的,而a[[1,2]]是自身数据的

>>> print(a.flags.owndata)
True
>>> print(a[1:3].flags.owndata)
False
>>> print(a[[1,2]].flags.owndata)
True

我们在看一下 ndarray.base 属性,果真印证了使用flags.owndata 查询的结果,a[1:3] 不是数据所有者,而数据来源数组a;

a[[1,2]] 是数据所有者,数据来源本身(None)

>>> print(a[[1,2]].base)
None
>>> print(a[1:3].base)
[1 2 3 4]

2. 视图

视图概念

我们通过上述简单例子,可以知道 a[1:3] 不是数据所有者,数据来源于对数组a的引用(浅拷贝)。

因此,我们应该对视图有了基本的认识了,看一下官方怎么描述视图的

No copy at All。 Simple assignments make no copy of objects or their data.

视图,是对原数组进行引用拷贝,共享原始数组的数据。

视图应用

视图在numpy中广泛使用,视图一般产生有两种场景:

  • 当对原始数组进行引用时
  • 当自身无数据,与原数组共享数据时
>>> import numpy as np
>>> a = np.array([1,2,3,4])
>>> b = a
>>> b is a
True
>>> id(a)
2247207679680
>>> id(b)
2247207679680
>>>

我们可以看到 a 与 b 是 同享同一个数据空间的

numpy 模块诸如索引、切片、函数view(),reshape()等返回视图结果

>>> arr = np.arange(10)
>>> arr_view = arr.view()
>>> arr.shape = (2,5)
>>> arr_reshape = arr.reshape(5,2)
# ndarray.base 属性
>>> print(arr.base)
None
>>> print(arr_view.base)
[[0 1 2 3 4]
 [5 6 7 8 9]]
>>> print(arr_reshape.base)
[[0 1 2 3 4]
 [5 6 7 8 9]]
# ndarray.flags.owndata 属性
>>> print(arr.flags.owndata)
True
>>> print(arr_view.flags.owndata)
False
>>> print(arr_reshape.flags.owndata)
False
>>>

视图优点

在 numpy 中 视图可以创建的对象可以节省内存空间,并且无需复制,提高查询速度

在视图中,创建的对象如果修改数据,原始数据也被修改。

3. 副本

副本概念

副本是对原数组进行完整拷贝(数据地址也会拷贝新的),与原始数组完全独立,相对于“深拷本”,不与原始数组共享数据。

同样截取官网,对副本的描述:

Deep Copy The copy method makes a complete copy of the array and its data

当改变副本的数据元素值时,虽然改变了副本与原数组相互独立,原始数组中元素值不会发生改变。

副本应用

  • 当进行切片操作时
  • 当需要与原始数组数据独立时

副本的实现我们可以直接使用 ndarray.copy()方法对原数组进行深拷贝

b = np.array([2,5,7])

c = b.copy()

c[1] = 8

print("b:",b)
print("c:",c)

print("c is b:",c is b)

# 查看 ndarray.base 属性å
print("b.base:",b.base)
print("c.base:",c.base)

# 查看 ndarray.flags.owndata
print("b.flags.owndata:",b.flags.owndata)
print("c.flags.owndata:",c.flags.owndata)

总结:

本期,我们对 numpy 模块中重要的概念视图和副本。

  • 视图,相当于浅拷贝,与原数组共享数据。
  • 副本,相当于深拷贝,与原数组数据相互独立

我们可以通过内存地址id()方法,同时借助ndarray.base、ndarray.flags来进一步分析区别

到此这篇关于Python numpy视图与副本的文章就介绍到这了,更多相关Python numpy视图与副本内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python numpy 模块介绍

    目录 1. numpy 简介 numpy 应用场景 numpy 模块安装 numpy 模块使用 2. numpy 特点 3. numpy 常用方法 4. 实例 前言: 在motplotlib的学习过程中,我们使用最多的就是numpy模块. numpy 模块被称为 matplotlib 模块绘制图表伴侣. xdm,接下来我们来对 matplotlib 伴侣-numpy 模块相关知识的学习 1. numpy 简介 numpy 模块是 Python 支持对大量数组进行科学计算的第三方库. numpy

  • Python NumPy实用函数笔记之allclose

    目录 numpy 数组及运算 创建数组 allclose() 总结 numpy 数组及运算 扩展库 numpy 是 Python 支持科学计算的重要扩展库,是数据分析和科学计算领域如 scipy.pandas.sklearn 等众多扩展库中必备的扩展库之一,提供了强大的 N 维数组及其相关的运算.复杂的广播函数.C/C++和Fortran代码集成工具以及线性代数.傅里叶变换和随机数生成等功能. 创建数组 数组是用来存储若干数据的连续内存空间,其中的元素一般是相同类型的,例如都是浮点数.数组运算是

  • Python中的Numpy 矩阵运算

    目录 在学习线性代数时我们所接触的矩阵之间的乘法是矩阵的叉乘,有这样一个前提: 若矩阵A是m*n阶的,B是p*q阶的矩阵,AB能相乘,首先得满足:n=p,即A的列数要等于B的行数.运算的方法如下图: 当时学线性代数时老师教的更为直观记法: 点乘则是这样: 假如有a,b两个矩阵,在Matlab中我们实现点乘和叉乘的方式分别如下: a.*b %表示点乘 a*b %表示叉乘 下面我们来看看python中的操作: import numpy as np a = np.arange(1, 10).resha

  • Python numpy视图与副本

    目录 1. 简单讲解 2. 视图 视图概念 视图应用 视图优点 3. 副本 副本概念 副本应用 前言: 继上一篇对numpy 模块之ndarray一文中对 ndarray 内存结构主要分为两部分: metdata :存放数组类型dtype.数组维度ndim.维度数量shape.维间距strides等raw bata:存放原始数据data 在 metdata 中包含着关于数组相关信息,可以帮助我们在数组ndarray中快速索引和解释指定的数据 除此了对数组进行索引操作外,也会对数组的原数据进行类似

  • python numpy库介绍

    目录 1.NumPy( Numeric Python) 2.numpy的引用 3.Ndarray 引入n维数组的意义 ndarray的组成 ndarray对象的属性 3.数据类型 ndarray数组的创建 adarray数组的变换 ndarray数组运算 4.索引与切片 5.随机数函数 6.统计函数 7.梯度函数 8.副本与视图 numpy线性代数 数组与标量之间的运算 常用numpy.linalg函数总结 1.NumPy( Numeric Python) numpy是一个开源的python科学

  • Python numpy中的ndarray介绍

    目录 1. 什么是 ndarray? ndarray 概念 ndarray 内部关系 2. ndarray 内存结构 ndarray 内存结构 3. ndarray vs list ndarray 特点 list 特点 在上一期python numpy 模块中对概述介绍了numpy 模块安装.使用方法.特点等入门知识. numpy 模块是一个开源的第三方Python库,常用于科学和工程领域,是科学Python和PyData 生态系统的核心. numpy 模块易学易用的特点,基本上覆盖了初学者到先

  • 基于Python Numpy的数组array和矩阵matrix详解

    NumPy的主要对象是同种元素的多维数组.这是一个所有的元素都是一种类型.通过一个正整数元组索引的元素表格(通常是元素是数字). 在NumPy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank,但是和线性代数中的秩不是一样的,在用python求线代中的秩中,我们用numpy包中的linalg.matrix_rank方法计算矩阵的秩,例子如下). 结果是: 线性代数中秩的定义:设在矩阵A中有一个不等于0的r阶子式D,且所有r+1阶子式(如果存在的话)全等于0,那末D称为矩阵

  • Python Numpy库常见用法入门教程

    本文实例讲述了Python Numpy库常见用法.分享给大家供大家参考,具体如下: 1.简介 Numpy是一个常用的Python科学技术库,通过它可以快速对数组进行操作,包括形状操作.排序.选择.输入输出.离散傅立叶变换.基本线性代数,基本统计运算和随机模拟等.许多Python库和科学计算的软件包都使用Numpy数组作为操作对象,或者将传入的Python数组转化为Numpy数组,因此在Python中操作数据离不开Numpy. Numpy的核心是ndarray对象,由Python的n维数组封装而来

  • python numpy库介绍

    目录 1.NumPy( Numeric Python) 2.numpy的引用 3.Ndarray 引入n维数组的意义 ndarray的组成 ndarray对象的属性 3.数据类型 ndarray数组的创建 adarray数组的变换 ndarray数组运算 4.索引与切片 5.随机数函数 6.统计函数 7.梯度函数 8.副本与视图 numpy线性代数 数组与标量之间的运算 常用numpy.linalg函数总结 1.NumPy( Numeric Python) numpy是一个开源的python科学

  • Python NumPy教程之索引详解

    目录 为什么我们需要 NumPy 使用索引数组进行索引 索引类型 基本切片和索引 高级索引 NumPy 或 Numeric Python 是一个用于计算同质 n 维数组的包.在 numpy 维度中称为轴. 为什么我们需要 NumPy 出现了一个问题,当 python 列表已经存在时,为什么我们需要 NumPy.答案是我们不能直接对两个列表的所有元素执行操作.例如,我们不能直接将两个列表相乘,我们必须逐个元素地进行.这就是 NumPy 发挥作用的地方. 示例 #1: # 演示需要 NumPy 的

  • 详解Python NumPy中矩阵和通用函数的使用

    目录 一.创建矩阵 二.从已有矩阵创建新矩阵 三.通用函数 四.算术运算 在NumPy中,矩阵是 ndarray 的子类,与数学概念中的矩阵一样,NumPy中的矩阵也是二维的,可以使用 mat . matrix 以及 bmat 函数来创建矩阵. 一.创建矩阵 mat 函数创建矩阵时,若输入已为 matrix 或 ndarray 对象,则不会为它们创建副本. 因此,调用 mat() 函数和调用 matrix(data, copy=False) 等价. 1) 在创建矩阵的专用字符串中,矩阵的行与行之

  • Python NumPy教程之数组的基本操作详解

    目录 Numpy中的N维数组(ndarray) 数组创建 数组索引 基本操作 数据类型 Numpy中的N维数组(ndarray) Numpy 中的数组是一个元素表(通常是数字),所有元素类型相同,由正整数元组索引.在 Numpy 中,数组的维数称为数组的秩.给出数组沿每个维的大小的整数元组称为数组的形状.Numpy 中的数组类称为ndarray.Numpy 数组中的元素可以使用方括号访问,并且可以使用嵌套的 Python 列表进行初始化. 例子 : [[ 1, 2, 3], [ 4, 2, 5]

  • Python NumPy教程之数组的创建详解

    目录 使用 List 创建数组 使用数组函数创建数组 使用 numpy 方法创建数组 重塑数组 展平数组 在 Numpy 中创建数组的方法 使用 List 创建数组 数组用于在一个变量中存储多个值.Python 没有对数组的内置支持,但可以使用 Python 列表代替. 例子 : arr = [1, 2, 3, 4, 5] arr1 = ["geeks", "for", "geeks"] # 用于创建数组的 Python 程序 # 使用列表创建数

  • Python Numpy教程之排序,搜索和计数详解

    目录 排序 搜索 Counting 排序 排序是指以特定格式排列数据.排序算法指定以特定顺序排列数据的方式.最常见的顺序是数字或字典顺序.在 Numpy 中,我们可以使用库中提供的各种函数(如 sort.lexsort.argsort 等)执行各种排序操作. numpy.sort(): 此函数返回数组的排序副本. # 导入库 import numpy as np # 沿第一轴排序 a = np.array([[12, 15], [10, 1]]) arr1 = np.sort(a, axis =

随机推荐