购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.2 基本类型的矩阵创建

NumPy运算库的核心是ndarray矩阵对象,它封装了同质数据类型的N维数组,而ndarray正是 N维数组 (N-dimensional array)的缩写。本节首先介绍如何由一个已有的数据序列(如列表和元组)创建一个ndarray矩阵对象。函数array()和asarray()可以帮助实现这一功能。array()函数的定义如下。

np.array(data, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

其中,data是已有的数据序列,如一个列表或者元组。dtype是待创建的ndarray矩阵对象中元素的数据类型。copy参数可用来提示ndarray是否需要复制。order参数可以是“C”或者“F”。后面会对这些参数进行详细讲解。

以下代码展示了分别从列表、元组和集合使用array()函数创建矩阵的过程。

运行结果如下。

对比发现,由array()函数创建的向量的数据类型是ndarray矩阵对象。将列表a_list打印输出时,是以“[1,2,3,4]”显示。而列表对象a_list和元组对象a_tuple转化为ndarray矩阵对象后,则是以“[1 2 3 4]”打印输出,元素中间是没有逗号的。最后由集合对象a_set转化的ndarray矩阵对象则是“{1,2,3,4}”。

在使用array()函数创建ndarray矩阵对象时,还可以使用dtype来指定矩阵元素的数据类型。以下代码例子展示了如何使用dtype。

运行结果如下。

Saving the data in the format of integer:[0 0 0]
Saving the data in the format of floating point:[-0.5440211  0.9129453 -0.9880316]
Datetime example: ['2005-02-25' '2011-12-25' '2020-09-20']
Updated datetime is: ['2005-06-05' '2012-07-12' '2021-07-17']

在这个例子中,列表sin_list存储了10°、20°和30°对应的正弦值,ndarray矩阵对象sin_list_int和sin_list_float的数据类型分别是整数型和浮点型,因此sin_list_int只存储了这些正弦值的整数部分,而sin_list_float则存储了浮点数形式的正弦值。另外,在这个例子中,使用dtype ="M"和dtype ="m"指定了两个ndarray矩阵对象date_example和date_increment的数据类型分别是日期型和日期间隔型,将这两个ndarray矩阵对象相加时,可以获得新的日期并存储在date_example_updated中。

列表和ndarray矩阵对象还有一个很大的不同之处在于,同一个列表中允许同时存储多种不同类型的数据,如整数型、浮点数和字符串等。但ndarray矩阵对象中的数据只能是同一种数据类型。以下例子展示了这个区别。

运行结果如下。

[10, 20, 30, 'James']
['10' '20' '30' 'James']
[b'10' b'20' b'30' b'James']
ValueError: invalid literal for int()with base 10: 'James'

在这个例子中,列表List_example中的变量元素包括整数型和字符串两种类型,若转化为ndarray矩阵对象时不指定dtype的参数,系统默认会把原来是整数型的变量都转化为字符串类型,这时候ndarray矩阵对象为“['10','20','30', 'James']”。当指定dtype为整数型“i”时,会出现错误提示,这是因为字符“James”不能被转化为整数型。

array()函数的copy参数可以用来选择是否复制原来的ndarray矩阵对象。这个copy参数默认为True。然而,即使copy参数为False,在很多情况下,NumPy仍然会复制并创建一个全新的ndarray矩阵对象。如图3-2所示为array()函数进行复制的几种情况。当原对象A是ndarray矩阵对象,且copy= False以及另一参数dtype不发生改变时,不进行复制,在其他情况下都会进行复制创建一个新的ndarray矩阵对象。

图3-2 array()函数copy参数的使用

以下代码展示了几个由array()函数生成的ndarray矩阵对象。在Case 1中,ndarray矩阵对象由列表生成,Case 2到Case 4均是从ndarray矩阵对象生成一个新的ndarray矩阵对象,区别在于:在Case 2中,是从一个ndarray矩阵对象生成一个新的ndarray矩阵对象;在Case 3中,指定copy = False,在Case 4中,虽然copy仍为False,但dtype更改为‘f’,用来表示数据类型是浮点数。

上述例子的运行结果如下所示。修改列表和原ndarray对象中某一个元素的值后再观察新生成的ndarray对象可发现,只有Case 3中的ndarray矩阵对象的元素发生更改,这是因为这个ndarray矩阵对象的指针仍然指向原来的ndarray矩阵对象。Case1、Case2和Case 4的ndarray矩阵元素没有发生更改,因此这三个ndarray矩阵对象都是复制后新创建的ndarray矩阵对象。

array()函数中的参数order可以用来指定数据在内存中的存储方式:行优先和列优先。order参数可以是“C”和“F”,分别对应行优先存储和列优先存储。这两者分别对应C语言和Fortran语言的内存存储方式。这里有必要讨论为什么NumPy提供了两种方式来存储数据。这主要是源自几何空间索引和二维矩阵索引的矛盾。如图3-3(a)所示,在几何空间的坐标体系里( x , y )的第一个数字代表横坐标,沿着水平方向或者行方向索引,第二个数字代表纵坐标,沿着垂直方向或者列方向索引。然而,二维矩阵中的行坐标和列坐标的索引与几何空间坐标体系的索引方式是相反的,矩阵元素的行坐标是沿着列的方向索引,而矩阵元素的列坐标是沿着行方向索引的,如图3-3(b)所示。

图3-3 几何空间索引和二维矩阵索引的矛盾

这一矛盾体现在数据的存储和索引方式中。如图3-4所示为一张风景图的数据。若以四方格的方式存储,根据行优先和列优先的方式,共有两种内存存储方式。当NumPy读取这一图片的数据时,若能根据图片原数据的存储方式(行优先或列优先),选择最优的数据索引方式能大大提高数据处理的速度,这正是array()函数的order参数提供的便利之处。NumPy部分其函数也有order参数,同样可以指定数据在内存中的存储方式,在本节和第4章会详细介绍这些函数。

除了array()函数以外,NumPy还提供了asarray()函数用来创建ndarray矩阵对象。实际上,asarray()函数可以看作array()函数的简化版,asarray()函数的定义如下。

图3-4 图片数据的存储

def asarray(data, dtype=None, order=None):
     return array(a, dtype, copy=False, order=order)

从asarray()函数的定义可以看出,它默认是不复制原ndarray矩阵对象的,然而正如图3-2中关于array()函数的讨论一样,即copy= False,但是当原对象是非ndarray矩阵对象,或者数据格式dtype参数发生变化时,NumPy仍然会复制并生成一个全新的ndarray矩阵对象。

一个ndarray矩阵对象具有众多 属性 (attribute)。如表3-4所示,这些属性包括ndarray的位数、形状、元素总个数和数据类型等。

表3-4 ndarray矩阵对象的属性

以下例子展示了如何使用ndarray矩阵对象的属性。

运行结果如下。 LrKjpsQ8nkFvIM+8wL8muLOFDICcYAN6LHad+RO6QZTgrAGVHAWeRcMxmAnsS/LZ

点击中间区域
呼出菜单
上一章
目录
下一章
×