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

作者:Daetalus 时间:2023-07-15 06:22:39 

前两篇文章对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
UnicodeU
VoidV

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


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

来源:http://blog.csdn.net/sunny2038/article/details/8907736

标签:numpy,数组
0
投稿

猜你喜欢

  • Python制作动态词频条形图的全过程

    2021-04-25 11:14:52
  • 使用sqlplus连接Oracle数据库问题

    2024-01-13 09:25:16
  • 对python中的six.moves模块的下载函数urlretrieve详解

    2023-10-20 00:23:45
  • zap接收gin框架默认的日志并配置日志归档示例

    2024-05-09 09:46:32
  • Python脚本实现监听服务器的思路代码详解

    2021-01-16 08:44:55
  • Python实现一个服务器监听多个客户端请求

    2022-10-18 15:32:14
  • python怎么判断素数

    2021-09-30 11:10:33
  • Go语言中的Array、Slice、Map和Set使用详解

    2023-06-24 07:29:03
  • 详解JavaScript中的this指向问题

    2023-08-23 00:52:03
  • Windows Server 2003 服务器安全设置--防火墙篇

    2010-07-22 22:45:00
  • python实现下载整个ftp目录的方法

    2023-01-31 01:45:17
  • MySQL中row_number的实现过程

    2024-01-23 15:08:54
  • 快速了解Python开发中的cookie及简单代码示例

    2023-05-29 11:04:05
  • python筛选出两个文件中重复行的方法

    2021-02-16 12:53:04
  • golang中之strconv包的具体使用方法

    2024-02-01 00:03:20
  • python网页请求urllib2模块简单封装代码

    2021-07-31 02:03:55
  • 微信小程序下载工具及调试详解

    2022-10-30 09:06:05
  • 教你怎么用PyCharm为同一服务器配置多个python解释器

    2022-01-29 10:22:21
  • Golang 使用Map实现去重与set的功能操作

    2024-02-21 14:54:21
  • 改变链接,让别人永远找不到你的程序

    2008-09-13 18:57:00
  • asp之家 网络编程 m.aspxhome.com