科学计算基础软件包Numpy学习 02

创建数组

以下介绍Numpy创建数组的一些常用方法,主要有:蛮力构造法,特殊数值法,随机数值法,定长分割法,重复构造法,网络构造法,自定义数据类型

蛮力构造法

蛮力构造法使用np.array()函数来创建数组,原型如下:

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

该函数看起来很多参数,但固定参数只有一个object,也就是和我们要创建的数组相似的数据结构,通常是Python列表和元组

>>> a = np.array([[1, 2, 3],[4, 5, 6]])  #创建2行3列数组
>>> a
array([[1, 2, 3],
       [4, 5, 6]])
>>> a.dtype
dtype('int32')

在np.array()函数的默认参数中,dtype参数用于指定数据类型,创建数组时,如果不指定数据类型,np.array()函数会根据object参数自动选择合适的数据类型,当然,也可以在创建数组时指定元素的数据类型

>>> a = np.array([[1,2,3],[4,5,6]],dtype=np.uint8) #创建8位无符号整型数组
>>> a
array([[1, 2, 3],
       [4, 5, 6], dtype=uint8)

蛮力构造法就是将想要创建数组的数据结构直接用python列表或元组写出来,再用np.array()函数转为数组,不适合创建体量较大的数组。

特殊数值法

这里特殊数值指的是0,1,空值。特殊数值法使用4个函数原型如下:

np.zeros(shape, dtype=float, order='C')
np.ones(shape, dtype=float, order='C')
np.empty(shape, dtype=float, order='C')
np.eye(N, M=None, k=0, dtype=float, order='C')

固定参数shape表示生成的数组结构,默认参数dtype用于指定数据类型(默认浮点型)。order参数几乎用不到,order参数指定的是数组在内存中的存储顺序,‘C’表示C语言使用的行优先方式,“F”表示Fortran语言使用的列优先方法。

>>> np.zeros(6)
array([0., 0., 0., 0., 0., 0.])
>>> np.zeros((2,3))
array([[0., 0., 0.],
       [0., 0., 0.]])
>>> np.ones((2,3),dtype=np.int)
array([[1, 1, 1],
       [1, 1, 1]])
>>> np.empty((2,3))
array([[0., 0., 0.],
       [0., 0., 0.]])
>>> np.eye(3, dtype=np.uint8)
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 1]], dtype=uint8)

随机数值法

和python的标准模块random类似,Numpy有一个random子模块,其功能更加强大。random子模块方法很多,这里只介绍3个常用的函数

np.random.random(size=None)
np.random.randint(low, high=None, size=None)
np.random.normal(loc=0.0, scale=1.0, size=None)

random()函数用于生成[0,1)区间内的随机浮点型数组,randint()函数用于生成[low,high)区间内的随机整型数组。参数size是一个元组,用于指定生成数组的结构,代码如下:

>>> np.random.random(3)
array([0.58621807, 0.12064618, 0.33679255])
>>> np.random.random((2,3))
array([[0.27955111, 0.80160663, 0.99680078],
       [0.74641081, 0.28596195, 0.47230631]])
>>> np.random.randint(5)
0
>>> np.random.randint(1, 5, size=(2,3))
array([[4, 3, 3],
       [4, 1, 4]])

normal() 函数用于生成以loc为均值,以scale为标准差的正态分部数组,下面用正态分布函数模拟生成1000位成年男性的身高数据(假定成年男性平均身高为170厘米,标准差为4厘米)

>>> import matplotlib.pyplot as plt #导入绘图模块
>>> import numpy as np
>>> tall = np.random.normal(170, 4, 1000) #生成正态分布数据
>>> bins = np.arange(156, 190, 2) #从156厘米到190厘米,每2厘米一个分段
>>> plt.hist(tall, bins) #绘制柱状图
(array([  0.,   8.,  13.,  54.,  98., 139., 178., 191., 164.,  94.,  39.,
        14.,   3.,   2.,   0.,   0.]), array([156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180,
       182, 184, 186, 188]), <a list of 16 Patch objects>)
>>> plt.show()  #显示图形

模拟成年男性身高(厘米)的正态分布数组如下:

定长分割法

定长分割法最常用的函数是arange(),它看起来和python的range()函数很像,只是前面多了一个字母a,另一个常用的定长分割函数是linspace(),类似于arange()函数,但功能更加强大,两个函数原型如下:

np.arange(start, stop, step, dtype=None)
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

arange()函数和python的range()函数用法相同,并且还可以接收浮点型参数,其代码如下:

>>> np.arange(5)
array([0, 1, 2, 3, 4])
>>> np.arange(5,11)
array([ 5,  6,  7,  8,  9, 10])
>>> np.arange(5,11,2)
array([5, 7, 9])
>>> np.arange(5.5,11,1.5)
array([ 5.5,  7. ,  8.5, 10. ])
>>> np.arange(3,15).reshape(3,4)
array([[ 3,  4,  5,  6],
       [ 7,  8,  9, 10],
       [11, 12, 13, 14]])

linspace()函数需要3个参数:一个起点,一个终点,一个返回元素的个数。linspace()函数返回的元素包括起点和终点,我们可以通过endpoint参数选择是否包含终点,其代码如下:

>>> np.linspace(0, 5, 5) #返回0到5之间的5个等距数值,包括0和5
array([0.  , 1.25, 2.5 , 3.75, 5.  ])
>>> np.linspace(0, 5, 5, endpoint=False) #返回5个等距数值,包括0但不包括5
array([0., 1., 2., 3., 4.])

重复构造法

重复构造法,顾名思义就是根据特定的规则对已有数组不断重复,从而生成新的数组,重复构造法主要使用repeat()和tile()这两个函数。
一般而言,repeat()函数用来重复数组元素。但如果被重复的数组是一个多维数组,且repeat()函数指定了axis参数,情况就会变得有些复杂

>>> import numpy as np
>>> a = np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> np.repeat(a, 3) #重复一维数组元素3次
array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
>>> a = np.arange(6).reshape((2,3))
>>> a
array([[0, 1, 2],
       [3, 4, 5]])
>>> np.repeat(a, 3) #重复二维数组元素3次,不指定轴
array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5])
>>> np.repeat(a, 3, axis=0) #重复二维数组元素3次,指定0轴
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [3, 4, 5],
       [3, 4, 5],
       [3, 4, 5]])
>>> np.repeat(a, 3, axis=1) #重复二维数组元素3次,指定1轴
array([[0, 0, 0, 1, 1, 1, 2, 2, 2],
       [3, 3, 3, 4, 4, 4, 5, 5, 5]])

tile意为铺地砖或贴墙砖,总之是把一块一块的地砖或墙转,一排排一列列地排列整齐。tile()函数也是这样,他将整个数组而非数组元素水平和垂直重复指定的次数。代码如下:

>>> import numpy as np
>>> a = np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> np.tile(a, 3) #重复一维数组3次
array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4])
>>> np.tile(a, (3,2)) #重复一维数组3行2列
array([[0, 1, 2, 3, 4, 0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4, 0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]])
>>> a = np.arange(6).reshape((2,3))
>>> a
array([[0, 1, 2],
       [3, 4, 5]])
>>> np.tile(a, 3) #重复二维数组3次
array([[0, 1, 2, 0, 1, 2, 0, 1, 2],
       [3, 4, 5, 3, 4, 5, 3, 4, 5]])
>>> np.tile(a, (2,3)) #重复二维数组2行3列
array([[0, 1, 2, 0, 1, 2, 0, 1, 2],
       [3, 4, 5, 3, 4, 5, 3, 4, 5],
       [0, 1, 2, 0, 1, 2, 0, 1, 2],
       [3, 4, 5, 3, 4, 5, 3, 4, 5]])

网格构造法

众所周知,研究地球表面需要经纬度坐标,经度从西经180°(-180°)到东经180°(180°),纬度从北纬90°(90°)到南纬90°(-90°),把经纬度线画出来,就形成了一个经纬度网格。经纬度网格是科学数据中常用的概念。
问题来了,如何用数组表示经纬度网格呢?一般有两种方式,第一种方式,用两个一维数组表示,下面的代码使用定长分割函数linspace(),将经度从-180°到180°分为间隔为10°的37个点,将纬度从90°到-90°分为间隔为10°的19个点,得到两个一维数组。

>>> import numpy as np
>>> lon = np.linspace(-180,180,37) #精度为10°,共计37个经度点
>>> lat = np.linspace(90,-90,19) #精度为10°,共计19个纬度点

经纬度网格的第二种表示方式是用两个二维数组分别表示经度网络和纬度网络,经度网格中每一列的元素都是相同的(同一个经度),纬度网格中每一行的元素都是相同的(同一个纬度)
生成二维经纬度网格的常用函数是np.meshgrid(),该函数以一维经度数组lon和一维纬度数组lat为参数,返回二维的经度数组和纬度数组,实现如下:

>>> import numpy as np
>>> lon = np.linspace(-180,180,37) #精度为10°,共计37个经度点
>>> lat = np.linspace(90,-90,19) #精度为10°,共计19个纬度点
>>> lons,lats = np.meshgrid(lon,lat)
>>> lons.shape
(19, 37)
>>> lats.shape
(19, 37)
>>> lons[:,0]
array([-180., -180., -180., -180., -180., -180., -180., -180., -180.,
       -180., -180., -180., -180., -180., -180., -180., -180., -180.,
       -180.])
>>> lats[0]
array([90., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90.,
       90., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90.,
       90., 90., 90., 90., 90., 90., 90., 90., 90., 90., 90.])

从上面的代码可以看到,二维经度数组lons的第0列所有元素都是-180°,二维纬度数组lats的第0行所有元素都是90°

自定义数据类型

首先思考一个问题:同一个列表中,元素类型既有字符串,又有整型和浮点型,将该列表转为数组,会报错吗?如果不报错,数组的数据类型是什么呢?下面用一个例子演示一下,其代码如下:

>>> import numpy as np
>>> np.array(['Anne',1.70,55])
array(['Anne', '1.7', '55'], dtype='<U4')

结果显示,数组会将所有元素的数据类型都转为‘<U4’类型,这里的U表示Unicode字符串;<表示字节顺序,意为小端在前(低位字节存储在最小地址中);4表示数组元素占用4字节,数组元素占用的字节数又所有元素中最长的那个元素决定。
接下来我们继续思考:怎么在数组中保留用以生成数组的列表中的元素类型呢?这就需要用到自定义数据类型了,其代码如下:

>>> import numpy as np
>>> mytype = np.dtype([('name','S32'),('tall',np.float),('bw',np.int)])
>>> np.array([('Anne',1.70,55)],dtype=mytype)
array([(b'Anne', 1.7, 55)],
      dtype=[('name', 'S32'), ('tall', '<f8'), ('bw', '<i4')])

唯有真理的光照,才能学会谦卑,走出自我的偏狭,自由而不放纵,独立而不狂狷,尽责而不懈怠。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值