Python 之 NumPy 简介和创建数组

简介: Python 之 NumPy 简介和创建数组

文章目录

一、NumPy 简介

1. 为什么要使用 NumPy

2. NumPy 数据类型

3. NumPy 数组属性

4. NumPy 的 ndarray 对象

二、numpy.array() 创建数组

1. 基础理论

2. 基础操作演示

3. numpy.array() 参数详解

三、numpy.arange() 生成区间数组

四、numpy.linspace() 创建等差数列

五、numpy.logspace() 创建等比数列

六、numpy.zeros() 创建全零数列

七、np.ones() 创建一数列


一、NumPy 简介


NumPy(Numerical Python)是 Python 的一种开源的数值计算扩展。

这种工具可用来存储和处理大型矩阵,比 Python 自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

使用 NumPy 可以方便的使用数据、矩阵进行计算,包含线性代数、傅里叶变化、随机数生成等大量函数。


1. 为什么要使用 NumPy


Numpy 是 Python 各种数据科学类库的基础库,比如:Scipy,Scikit-Learn、TensorFlow、pandas等。

对于同样的数值计算任务,使用 NumPy 比直接使用 Python 代码实现有如下优点:

(1) 代码更简洁:NumPy 直接以数组、矩阵为粒度计算并且支撑大量的数学函数,而 python 需要用 for 循环从底层实现;

(2) 性能更高效:NumPy 的数组存储效率和输入输出计算性能,比 Python 使用 List 或者嵌套 List 好很多。

这里有两点需要注意需要注意是,其一,Numpy 的数据存储和 Python 原生的 List 是不一样的。

其二,NumPy 的大部分代码都是 C 语言实现的,这是 Numpy 比纯 Python 代码高效的原因。


2. NumPy 数据类型


  • NumPy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。
  • 下表列举了常用 NumPy 基本类型:


150.png


157.png


NumPy 的数值类型实际上是 dtype 对象的实例,并对应唯一的字符,包括 np.bool_,np.int32,np.float32,等等。


3. NumPy 数组属性


NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。

在 NumPy 中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。

比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。

很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。

NumPy 的数组中比较重要 ndarray 对象属性有:

158.png


4. NumPy 的 ndarray 对象


  • NumPy 定义了一个 n 维数组对象,简称 ndarray 对象,它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块。
  • ndarray 对象采用了数组的索引机制,将数组中的每个元素映射到内存块上,并且按照一定的布局对内存块进行排列(行或列)

4090ab1b31784c8db77acf03ca8c6153.png


二、numpy.array() 创建数组

1. 基础理论


  • 基本的 ndarray 是使用 NumPy 中的数组函数创建的,如下所示:
numpy.array



它从任何暴露数组接口的对象,或从返回数组的任何方法创建一个 ndarray。

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


上面的构造器接受以下参数:

159.png


2. 基础操作演示

  • 在代码编写之前,我们需要线引入 NumPy。
# 注意默认都会给numpy包设置别名为np
import numpy as np


  • NumPy 引入完成后,实现 array 创建数组。
  • 在 array() 函数当中,括号内可以是列表、元组、数组、迭代对象,生成器等。
  • 其中,列表和元组的整体相同,但是列表属于可变序列,它的元素可以随时修改或删除,元组是不可变序列,其中元素不可修改,只能整体替换。
  • (1) 列表:
np.array([1,2,3,4,5])
#array([1, 2, 3, 4, 5])
  • (2) 元组:
np.array((1,2,3,4,5))
#array([1, 2, 3, 4, 5])


  • (3) 数组:
a = np.array([1,2,3,4,5]) #创建一个数组
np.array(a)
#array([1, 2, 3, 4, 5])


  • 4) 迭代对象:
np.array(range(10))
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])


  • 5) 生成器:
np.array([i**2 for i in range(10)])
#array([ 0,  1,  4,  9, 16, 25, 36, 49, 64, 81])


  • 当数组内的元素数据类型不相同时,那么数组内哪种数据类型存储的结果最大,就按哪种数据类型进行存储。
  • 如下例子,在数组当中,包含整型,浮点型和字符串,其中字符串的数据类型存储结果最大,因此,数组内的所有元素均按字符串进行存储。
np.array([1,1.5,3,4.5,'5'])
#array(['1', '1.5', '3', '4.5', '5'], dtype='<U32')


  • 1) 整型:
ar1 = np.array(range(10))   # 整型
ar1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])


  • (2) 浮点型(浮点型的数据存储大于整型的数据存储,因此全部转换为浮点型):
ar2 = np.array([1,2,3.14,4,5])   
ar2
#array([1.  , 2.  , 3.14, 4.  , 5.  ])



(3) 二维数组(嵌套序列(列表,元组均可))

ar3 = np.array([
                [1,2,3],
                ('a','b','c')
               ])   
ar3
#array([['1', '2', '3'],
#       ['a', 'b', 'c']], dtype='<U11')


  • 4) 当二维数组嵌套序列数量不一致:
ar4 = np.array([[1,2,3],('a','b','c','d')])   
ar4
#array([list([1, 2, 3]), ('a', 'b', 'c', 'd')], dtype=object)


上述例子的秩是 1,可以通过 ar4.ndim 进行查看。


3. numpy.array() 参数详解

  • (1) 设置 dtype 参数,默认自动识别。
a = np.array([1,2,3,4,5])
print(a)
# 设置数组元素类型
has_dtype_a = np.array([1,2,3,4,5],dtype='float')
has_dtype_a
#[1 2 3 4 5]
#array([1., 2., 3., 4., 5.])


  • 如果将浮点型的数据,设置为整形,那么,数组内元素会自动舍弃尾数,转换为整型数据,具体输出如下所示。
np.array([1.1,2.5,3.8,4,5],dtype='int')
#array([1, 2, 3, 4, 5])


  • (2) 设置 copy 参数,默认为 True。
  • 我们设置 a 数组,然后,通过 a 数组复制得出 b 数组,此时,a 数组和 b 数组的地址不相同,创建了新的对象。


  • 那么,对 a 数组和 b 数组的任意修改都不会影响另一个数组的元素。
a = np.array([1,2,3,4,5])
b = np.array(a)
print('a:', id(a), '  b:', id(b))
print('以上看出a和b的内存地址')
b[0] = 10
print(a)
#a: 2066732212352   b: 2066732213152
#以上看出a和b的内存地址
#[1 2 3 4 5]



  • 当我们修改 b 数组的元素时,a 数组不会发生变化。
b[0] = 10
print('a:', a,'  b:', b)
#a: [1 2 3 4 5]   b: [10  2  3  4  5]


  • 当设置 copy 参数为 Fasle 时,不会创建副本,两个变量会指向相同的内容地址,没有创建新的对象。
  • 此时,由于 a 数组和 b 数组指向的是相同的内存地址,因此当修改 b 数组的元素时,a 数组对应的元素会发生变化。
a = np.array([1,2,3,4,5])
b = np.array(a, copy=False)
print('a:', id(a), '  b:', id(b))
print('以上看出a和b的内存地址')
b[0] = 10
print('a:',a,'  b:',b)
#a: 2066732267520   b: 2066732267520
#以上看出a和b的内存地址
#a: [10  2  3  4  5]   b: [10  2  3  4  5]


  • (3) ndmin 用于指定数组的维度。
  • 将一维数组转换为二维数组。
a = np.array([1,2,3])
print(a)​
a = np.array([1,2,3], ndmin=2)
a​
#[1 2 3]
#array([[1, 2, 3]])



(4) subok 参数,类型为 bool 值,默认 False。为 True 时,使用 object 的内部数据类型;False:使用 object 数组的数据类型。

首先,创建一个 a 矩阵,然后输出 a 矩阵的数据类型,便于后面的比较。

其次,通过 a 矩阵生成 at 和 af 两个数组,at 数组的 subok 参数设置为 True,at 数组的 subok 参数不设置,即默认为 False。

  • 最后,输出 at 数组和 af 数组的数据类型,用于比较观察。
a = np.mat([1,2,3,4])
print(type(a))
​at = np.array(a,subok=True)
af = np.array(a) 
print('at,subok为True:',type(at))
print('af,subok为False:',type(af))
print(id(at),id(a))​
#<class 'numpy.matrix'>
#at,subok为True: <class 'numpy.matrix'>
#af,subok为False: <class 'numpy.ndarray'>
#2066738151720 2066738151608



  • 书写代码时需要注意的内容:
  • 先定义一个 a 数组。
a = np.array([2,4,3,1]


  • 在定义 b 数组时,如果想复制 a 数组,有如下几种方案:
  • (1) 使用 np.array()。
  • (2) 使用数组的 copy() 方法。
b = np.array(a)
print('b = np.array(a):',id(b),id(a))
​c = a.copy()
print('c = a.copy():',id(c),id(a))
#b = np.array(a): 2066731363744 2066731901216
#c = a.copy(): 2066732267520 2066731901216



  • 注意不能直接使用 = 号复制,直接使用 = 号,会使 2 个变量指向相同的内存地址。

三、numpy.arange() 生成区间数组

  • 根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。
numpy.arange(start, stop, step, dtype)


其参数含义如下:

序号 参数 描述说明
1 start 起始值,默认为 0
2 stop 终止值(不包含)
3 step 步长,默认为 1
4 dtype 返回 ndarray 的数据类型,如果没有提供,则会使用输入数据的类型。



  • 如果只有一个参数,那么起始值就是 0,终止值就是那个参数,步长就是 1。
  • 如果有两个参数,那么,第一个参数就是起始值,第二个参数就是终止值。
np.arange(10)
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])



  • 可以使用浮点型数值。
np.arange(3.1)
#array([0., 1., 2., 3.])


  • 返回浮点型的,也可以指定类型。
x = np.arange(5, dtype =  float)  
x
#array([0., 1., 2., 3., 4.])


  • 设置了起始值、终止值及步长:
  • (1) 起始值是 10,终止值是 20,步长是 2。
np.arange(10,20,2)
#array([10, 12, 14, 16, 18])


  • (1) 起始值是 0,终止值是 20,步长是 3。
ar2 = np.arange(0,20,3)
print(ar2)
ar3 = np.arange(20,step=3) #指定传参
ar3
​#[ 0  3  6  9 12 15 18]
#array([ 0,  3,  6,  9, 12, 15, 18])


  • 如果数组太大而无法打印,NumPy 会自动跳过数组的中心部分,并只打印边角。
np.arange(10000)
#array([   0,    1,    2, ..., 9997, 9998, 9999])


四、numpy.linspace() 创建等差数列

  • 返回在间隔 [开始,停止] 上计算的 num 个均匀间隔的样本。数组是一个等差数列构成。
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

其参数含义如下:

787.png


  • 以下例子用到三个参数,设置起始点为 1 ,终止点为 10,数列个数为 10。
a = np.linspace(1,10,10)
a
#array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])


  • 如果,我们将 endpoint 设置为 False,就不会包含 10,此时,默认步长是 50。
a = np.linspace(1,10,endpoint=False)
a
#array([1.  , 1.18, 1.36, 1.54, 1.72, 1.9 , 2.08, 2.26, 2.44, 2.62, 2.8 ,
#       2.98, 3.16, 3.34, 3.52, 3.7 , 3.88, 4.06, 4.24, 4.42, 4.6 , 4.78,
#       4.96, 5.14, 5.32, 5.5 , 5.68, 5.86, 6.04, 6.22, 6.4 , 6.58, 6.76,
#       6.94, 7.12, 7.3 , 7.48, 7.66, 7.84, 8.02, 8.2 , 8.38, 8.56, 8.74,
#       8.92, 9.1 , 9.28, 9.46, 9.64, 9.82])


  • 以下实例用到三个参数,设置起始位置为 2.0,终点为 3.0,数列个数为 5。
ar1 = np.linspace(2.0, 3.0, num=5)
ar1
#array([2.  , 2.25, 2.5 , 2.75, 3.  ])


  • 将参数 endpoint 设置为 False 时,不包含终止值,
ar1 = np.linspace(2.0, 3.0, num=5, endpoint=False)
ar1
#array([2. , 2.2, 2.4, 2.6, 2.8])


设置 retstep 显示计算后的步长。

ar1 = np.linspace(2.0,3.0,num=5, retstep=True)
print(ar1)
type(ar1)
#(array([2.  , 2.25, 2.5 , 2.75, 3.  ]), 0.25)
#tuple

将 endpoint 设置为 False,不包含终止值,再设置 retstep 显示计算后的步长。

ar1 = np.linspace(2.0,3.0,num=5,endpoint=False,retstep=True)
ar1
#(array([2. , 2.2, 2.4, 2.6, 2.8]), 0.2)

等差数列在线性回归经常作为样本集,例如:生成 x_data,值为 [0, 100] 之间 500 个等差数列数据集合作为样本特征,根据目标线性方程 y = 3 × x + 2 ,生成相应的标签集合 y_data。


x_data = np.linspace(0,100,500)
x_data


五、numpy.logspace() 创建等比数列

  • 返回在间隔 [开始,停止] 上计算的 num 个均匀间隔的样本。数组是一个等比数列构成。
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)


321.png

a = np.logspace(0,9,10,base=2)
a
#array([  1.,   2.,   4.,   8.,  16.,  32.,  64., 128., 256., 512.])

322.png

np.logspace(1,5,3,base=2)
#array([ 2.,  8., 32.])
  • 取得 1 到 2 之间 10 个常用对数。
np.logspace(1.0,2.0,num=10)
#array([ 10.        ,  12.91549665,  16.68100537,  21.5443469 ,
#        27.82559402,  35.93813664,  46.41588834,  59.94842503,
#        77.42636827, 100.        ])


六、numpy.zeros() 创建全零数列

  • 创建指定大小的数组,数组元素以 0 来填充。
numpy.zeros(shape, dtype = float, order = 'C')


其参数含义如下:

序号 参数 描述说明
1 shape 数组形状
2 dtype 数据类型,可选



  • 默认的数据类型是浮点数。
np.zeros(5)
#array([0., 0., 0., 0., 0.])



  • 生成一个 2 行 2 列的全 0 数组。
np.zeros((2,2))
#array([[0., 0.],
#       [0., 0.]])



  • 使用 zeros_like 可以返回具有与给定数组相同的形状和类型的零数组。
ar1 = np.array([[1,2,3],[4,5,6]])
np.zeros_like(ar1)
#array([[0, 0, 0],
#       [0, 0, 0]])



七、np.ones() 创建一数列

  • 生成元素全部是 1 的数列。
ar5 = np.ones(9)
ar6 = np.ones((2,3,4))
ar7 = np.ones_like(ar3)
print('ar5:',ar5)
print('ar6:',ar6)
print('ar7:',ar7)
#ar5: [1. 1. 1. 1. 1. 1. 1. 1. 1.]
#ar6: [[[1. 1. 1. 1.]
#  [1. 1. 1. 1.]
#  [1. 1. 1. 1.]]
#
# [[1. 1. 1. 1.]
#  [1. 1. 1. 1.]
#  [1. 1. 1. 1.]]]
#ar7: [1 1 1 1 1 1 1]





















相关文章
|
3天前
|
Shell Python
python|闲谈2048小游戏和数组的旋转及翻转和转置
python|闲谈2048小游戏和数组的旋转及翻转和转置
21 1
|
8天前
|
存储 算法 数据处理
《Numpy 简易速速上手小册》第3章:Numpy 数组操作与变换(2024 最新版)
《Numpy 简易速速上手小册》第3章:Numpy 数组操作与变换(2024 最新版)
30 0
|
8天前
|
存储 数据采集 数据挖掘
《Numpy 简易速速上手小册》第2章:Numpy 数据类型和数组构造(2024 最新版)
《Numpy 简易速速上手小册》第2章:Numpy 数据类型和数组构造(2024 最新版)
24 0
|
9天前
|
存储 机器学习/深度学习 数据挖掘
自定义数据类型与NumPy结构数组详解
【4月更文挑战第17天】本文详细介绍了NumPy中的自定义数据类型和结构数组。通过`numpy.dtype`可创建自定义数据类型,如示例中的包含整数和浮点数字段的数组。结构数组能存储不同类型的元素,每行作为一个记录,包含多个字段。创建结构数组时,定义字段及其数据类型,然后通过字段名进行访问和操作。掌握这些技术能提升数据处理效率和灵活性,尤其在科学计算和数据分析领域。
|
9天前
|
搜索推荐 数据挖掘 数据处理
NumPy数组统计与排序方法全览
【4月更文挑战第17天】本文介绍了NumPy在Python中的数组统计和排序功能。主要包括计算平均值、标准差和方差的`np.mean()`, `np.std()`, `np.var()`方法,以及求最大值、最小值、百分位数的功能。在排序方面,讲解了基本排序的`np.sort()`,获取排序索引的`np.argsort()`,逆序排序和随机排序的方法。这些工具对于数据分析和科学计算十分实用,能有效提升数据处理效率。
|
9天前
|
存储 数据处理 Python
NumPy数组运算:元素级与广播机制剖析
【4月更文挑战第17天】NumPy是Python数值计算库,提供元素级运算和广播机制。元素级运算针对数组每个元素单独计算,如加法、减法等;广播机制允许不同形状数组间运算,通过扩展小数组形状匹配大数组。了解这两点能帮助更好地运用NumPy进行数值计算和数据处理。
|
9天前
|
存储 索引 Python
深入解析NumPy数组的形状与重塑
【4月更文挑战第17天】本文深入解析了NumPy数组的形状和重塑。数组形状是表示数组维度和大小的元组,可通过`shape`属性获取。重塑允许改变数组形状而不改数据,需保证元素总数不变。`reshape`方法用于重塑,其中`-1`可让NumPy自动计算尺寸。注意重塑遵循元素总数相等、仅一次`-1`、内存存储顺序及返回新数组的原则。理解和掌握这些概念对高效使用NumPy处理多维数组至关重要。
|
9天前
|
Python
用Python的Numpy求解线性方程组
用Python的Numpy求解线性方程组
10 0
|
13天前
|
存储 安全 数据处理
python如何将数据写到数组里
【4月更文挑战第12天】
|
14天前
|
网络协议 Java API
Python网络编程基础(Socket编程)Twisted框架简介
【4月更文挑战第12天】在网络编程的实践中,除了使用基本的Socket API之外,还有许多高级的网络编程库可以帮助我们更高效地构建复杂和健壮的网络应用。这些库通常提供了异步IO、事件驱动、协议实现等高级功能,使得开发者能够专注于业务逻辑的实现,而不用过多关注底层的网络细节。