深入理解NumPy简明教程---数组3(组合)

前两篇文章对NumPy数组做了基本的介绍,本篇文章对NumPy数组进行较深入的探讨。首先介绍自定义类型的数组,接着数组的组合,最后介绍数组复制方面的问题。

自定义结构数组

通过NumPy也可以定义像C语言那样的结构类型。在NumPy中定义结构的方法如下:

定义结构类型名称;定义字段名称,标明字段数据类型。

student= dtype({'names':['name', 'age', 'weight'], 'formats':['S32', 'i','f']}, align = True) 

这里student是自定义结构类型的名称,使用dtype函数创建,在第一个参数中,'names'和'formats'不能改变,names中列出的是结构中字段名称,formats中列出的是对应字段的数据类型。S32表示32字节长度的字符串,i表示32位的整数,f表示32位长度的浮点数。最后一个参数为True时,表示要求进行内存对齐。

字段中使用NumPy的字符编码来表示数据类型。更详细的数据类型见下表。

数据类型 字符编码
整数 i
无符号整数 u
单精度浮点数 f
双精度浮点数 d
布尔值 b
复数 D
字符串 S
Unicode U
Void V

在定义好结构类型之后,就可以定义以该类型为元素的数组了:

a= array([(“Zhang”, 32, 65.5), (“Wang”, 24, 55.2)], dtype =student) 

除了在每个元素中依次列出对应字段的数据外,还需要在array函数中最后一个参数指定其所对应的数据类型。

注:例子来源于张若愚的Python科学计算艺术的29页。更多关于dtype的内容请参考《NumPy for Beginner》一书的第二章。

组合函数

这里介绍以不同的方式组合函数。首先创建两个数组:

>>> a = arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
   [3, 4, 5],
   [6, 7, 8]])
>>> b = 2 * a
>>> b
array([[ 0, 2, 4],
  [ 6, 8, 10],
  [12, 14, 16]])

水平组合

>>> hstack((a, b))
array([[ 0, 1, 2, 0, 2, 4],
  [ 3, 4, 5, 6, 8, 10],
  [ 6, 7, 8, 12, 14, 16]])

也可通过concatenate函数并指定相应的轴来获得这一效果:

>>> concatenate((a, b), axis=1)
array([[ 0, 1, 2, 0, 2, 4],
  [ 3, 4, 5, 6, 8, 10],
  [ 6, 7, 8, 12, 14, 16]])

垂直组合

>>> vstack((a, b))
array([[ 0, 1, 2],
  [ 3, 4, 5],
  [ 6, 7, 8],
  [ 0, 2, 4],
  [ 6, 8, 10],
  [12, 14, 16]])

同样,可通过concatenate函数,并指定相应的轴来获得这一效果。

>>> concatenate((a, b), axis=0)
array([[ 0, 1, 2],
  [ 3, 4, 5],
  [ 6, 7, 8],
  [ 0, 2, 4],
  [ 6, 8, 10],
  [12, 14, 16]])

深度组合

另外,还有深度方面的组合函数dstack。顾名思义,就是在数组的第三个轴(即深度)上组合。如下:

>>> dstack((a, b))
array([[[ 0, 0],
  [ 1, 2],
  [ 2, 4]], 

  [[ 3, 6],
  [ 4, 8],
  [ 5, 10]], 

  [[ 6, 12],
  [ 7, 14],
  [ 8, 16]]])

仔细观察,发现对应的元素都组合成一个新的列表,该列表作为新的数组的元素。

行组合

行组合可将多个一维数组作为新数组的每一行进行组合:

>>> one = arange(2)
>>> one
array([0, 1])
>>> two = one + 2
>>> two
array([2, 3])
>>> row_stack((one, two))
array([[0, 1],
  [2, 3]])

对于2维数组,其作用就像垂直组合一样。

列组合

列组合的效果应该很清楚了。如下:

>>> column_stack((oned, twiceoned))
array([[0, 2],
  [1, 3]]) 

对于2维数组,其作用就像水平组合一样。

分割数组

在NumPy中,分割数组的函数有hsplit、vsplit、dsplit和split。可将数组分割成相同大小的子数组,或指定原数组分割的位置。

水平分割

>>> a = arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
  [3, 4, 5],
  [6, 7, 8]])
>>> hsplit(a, 3)
[array([[0],
  [3],
  [6]]),
 array([[1],
  [4],
  [7]]),
 array([[2],
  [5],
  [8]])]

也调用split函数并指定轴为1来获得这样的效果:

split(a, 3, axis=1)

垂直分割

垂直分割是沿着垂直的轴切分数组:

>>> vsplit(a, 3)
>>> [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])] 

同样,也可通过solit函数并指定轴为1来获得这样的效果:

>>> split(a, 3, axis=0) 

面向深度的分割

dsplit函数使用的是面向深度的分割方式:

>>> c = arange(27).reshape(3, 3, 3)
>>> c
array([[[ 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]]])
>>> dsplit(c, 3)
[array([[[ 0],
  [ 3],
  [ 6]], 

  [[ 9],
  [12],
  [15]], 

  [[18],
  [21],
  [24]]]),
 array([[[ 1],
  [ 4],
  [ 7]], 

  [[10],
  [13],
  [16]], 

  [[19],
  [22],
  [25]]]),
 array([[[ 2],
  [ 5],
  [ 8]], 

  [[11],
  [14],
  [17]], 

  [[20],
  [23],
  [26]]])]

复制和镜像(View)

当运算和处理数组时,它们的数据有时被拷贝到新的数组有时不是。这通常是新手的困惑之源。这有三种情况:

完全不复制

简单的赋值,而不复制数组对象或它们的数据。

>>> a = arange(12)
>>> b = a  #不创建新对象
>>> b is a   # a和b是同一个数组对象的两个名字
True
>>> b.shape = 3,4 #也改变了a的形状
>>> a.shape
(3, 4)
    Python 传递不定对象作为参考4,所以函数调用不拷贝数组。
 >>> def f(x):
...  print id(x)
...
>>> id(a)  #id是一个对象的唯一标识
148293216
>>> f(a)
148293216

视图(view)和浅复制

不同的数组对象分享同一个数据。视图方法创造一个新的数组对象指向同一数据。

>>> c = a.view()
>>> c is a
False
>>> c.base is a  #c是a持有数据的镜像
True
>>> c.flags.owndata
False
>>>
>>> c.shape = 2,6 # a的形状没变
>>> a.shape
(3, 4)
>>> c[0,4] = 1234  #a的数据改变了
>>> a
array([[ 0, 1, 2, 3],
  [1234, 5, 6, 7],
  [ 8, 9, 10, 11]])

切片数组返回它的一个视图:

>>> s = a[ : , 1:3]  # 获得每一行1,2处的元素
>>> s[:] = 10   # s[:] 是s的镜像。注意区别s=10 and s[:]=10
>>> a
array([[ 0, 10, 10, 3],
  [1234, 10, 10, 7],
  [ 8, 10, 10, 11]])

深复制

这个复制方法完全复制数组和它的数据。

 >>> d = a.copy()  #创建了一个含有新数据的新数组对象
>>> d is a
False
>>> d.base is a  #d和a现在没有任何关系
False
>>> d[0,0] = 9999
>>> a
array([[ 0, 10, 10, 3],
  [1234, 10, 10, 7],
  [ 8, 10, 10, 11]])

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 深入理解NumPy简明教程---数组2

    NumPy数组(2.数组的操作) 基本运算 数组的算术运算是按元素逐个运算.数组运算后将创建包含运算结果的新数组. >>> a= np.array([20,30,40,50]) >>> b= np.arange( 4) >>> b array([0, 1, 2, 3]) >>> c= a-b >>> c array([20, 29, 38, 47]) >>> b**2 array([0, 1, 4,

  • 深入理解NumPy简明教程---数组1

    目前我的工作是将NumPy引入到Pyston中(一款Dropbox实现的Python编译器/解释器).在工作过程中,我深入接触了NumPy源码,了解其实现并提交了PR修复NumPy的bug.在与NumPy源码以及NumPy开发者打交道的过程中,我发现当今中文NumPy教程大部分都是翻译或参考英文文档,因此导致了许多疏漏.比如NumPy数组中的broadcast功能,几乎所有中文文档都翻译为"广播".而NumPy的开发者之一,回复到"broadcast is a compoun

  • 深入理解NumPy简明教程---数组3(组合)

    前两篇文章对NumPy数组做了基本的介绍,本篇文章对NumPy数组进行较深入的探讨.首先介绍自定义类型的数组,接着数组的组合,最后介绍数组复制方面的问题. 自定义结构数组 通过NumPy也可以定义像C语言那样的结构类型.在NumPy中定义结构的方法如下: 定义结构类型名称:定义字段名称,标明字段数据类型. student= dtype({'names':['name', 'age', 'weight'], 'formats':['S32', 'i','f']}, align = True) 这里

  • 详解Numpy中的数组拼接、合并操作(concatenate, append, stack, hstack, vstack, r_, c_等)

    Numpy中提供了concatenate,append, stack类(包括hsatck.vstack.dstack.row_stack.column_stack),r_和c_等类和函数用于数组拼接的操作. 各种函数的特点和区别如下标: concatenate 提供了axis参数,用于指定拼接方向 append 默认先ravel再拼接成一维数组,也可指定axis stack 提供了axis参数,用于生成新的维度 hstack 水平拼接,沿着行的方向,对列进行拼接 vstack 垂直拼接,沿着列的

  • Numpy数组的组合与分割实现的方法

    目录 数组的组合 1.水平组合 2.垂直组合 3.行组合和列组合 4.深度组合 数组的分割 1.水平分割 1.1hsplit函数 1.2split函数 2.垂直分割 3.深度分割 在介绍数组的组合和分割前,我们需要先了解数组的维(ndim)和轴(axis)概念. 如果数组的元素是数组,即数组嵌套数组,我们就称其为多维数组.几层嵌套就称几维.比如形状为(a,b)的二维数组就可以看作两个一维数组,第一个一维数组包含a个一维数组,第二个一维数组包含b个数据. 每一个一维线性数组称为一个轴.二维数组的第

  • Python 机器学习库 NumPy入门教程

    NumPy是一个Python语言的软件包,它非常适合于科学计算.在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础库. 本文是对它的一个入门教程. 介绍 NumPy是一个用于科技计算的基础软件包,它是Python语言实现的.它包含了: 强大的N维数组结构 精密复杂的函数 可集成到C/C++和Fortran代码的工具 线性代数,傅里叶变换以及随机数能力 除了科学计算的用途以外,NumPy也可被用作高效的通用数据的多维容器.由于它适用于任意类型的数据,这使得NumPy可以无缝和

  • python扩展库numpy入门教程

    目录 一.numpy是什么? 二.numpy数组 2.1 数组使用 2.2 创建数组 1. 使用empty创建空数组 2. 使用arange函数创建 3. 使用zeros函数生成数组 4. ones函数生成数组 5. diag函数生成对角矩阵 6. N维数组 2.3 访问数组元素 三.了解矩阵 3.1 广播 一.numpy是什么? 扩展库numpy是Python支持科学计算的重要扩展库,是数据分析和科学计算领域如scipy.pandas.sklearn 等众多扩展库中的必备扩展库之一,提供了强大

  • 深入理解JAVA中的聚集和组合的区别与联系

    选自<JAVA语言程序设计-基础篇(原书第8版)> 定义:一个对象可以包含另一个对象.这两个对象之间的关系称为组合(composition). 组合实际上是聚集关系的一种特殊形式.聚集模拟了具有(has-a)关系,表示两个对象之间的归属关系.归属关系中的所有者对象称为聚集对象(aggregation object),而它的类称为聚集类(aggregating class).归属关系中的从属对象称为被聚集类(aggregated object),而它的类被称为被聚集类(aggregated cl

  • Python使用numpy模块创建数组操作示例

    本文实例讲述了Python使用numpy模块创建数组操作.分享给大家供大家参考,具体如下: 创建数组 创建ndarray 创建数组最简单的方法就是使用array函数.它接收一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组. array函数创建数组 import numpy as np ndarray1 = np.array([1, 2, 3, 4]) ndarray2 = np.array(list('abcdefg')) ndarray3 = np.array([

  • 浅谈Python numpy创建空数组的问题

    一.问题描述: 有一个shape为(308, 2)的二维数组,以及单独的一个数字,需要保存到csv文件中,这个单独的数字让其保存到第3列第一行的位置. 二.具体的实现: 首先要想把一个(308, 2)的二维数组和一个数字给拼接起来,直接拼接没办法实现,因为行数和列数都不同的两个ndarry是无法拼接的(此处按照目前我学的理解,是无法直接拼接的,如果可以的话,麻烦评论一下). 然后我首先想到的解决方法就是先建一个(308,1)的二维数组,然后令这个二维数组的第一个元素设置成那个数字,然后进行拼接,

随机推荐