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]





















相关文章
|
5天前
|
索引 Python
NumPy 教程 之 Numpy 数组操作 28
NumPy 提供多种数组操作功能,包括修改形状、翻转、连接和分割等。本教程重点介绍元素的添加与删除,如使用 `resize`、`append`、`insert` 和 `delete` 函数。其中 `numpy.insert` 可在指定索引前插入值,支持标量或数组插入。示例展示了不同情况下 `insert` 的使用方法,包括不指定轴时的数组扁平化插入,以及沿特定轴进行广播插入。
18 2
|
4天前
|
Python
NumPy 教程 之 Numpy 数组操作 29
NumPy 提供多种数组操作函数,如修改形状、翻转和连接等。本教程重点介绍元素的添加与删除,包括 `resize`、`append`、`insert` 和 `delete` 函数。`numpy.delete` 用于从数组中删除指定元素,参数包括 `arr`(输入数组)、`obj`(待删元素)和 `axis`(删除轴)。示例展示了如何使用 `numpy.delete` 删除一维和二维数组中的元素。
15 4
|
4天前
|
数据挖掘 索引 Python
NumPy 教程 之 Numpy 数组操作 30
展示了如何使用`numpy.unique`去除数组中的重复值,并获取额外信息如索引和计数。示例中,数组`a`的重复值被去除,打印出唯一值及其在原数组中的首次出现索引、对应原值的索引以及各唯一元素的出现次数。这有助于数据分析时简化数据集。
12 2
|
4天前
|
存储 缓存 索引
Python中的NumPy库详解
Python中的NumPy库详解
|
6天前
|
机器学习/深度学习 数据可视化 API
Python Numpy 切片和索引(高级索引、布尔索引、花式索引)
Python Numpy 切片和索引(高级索引、布尔索引、花式索引)
16 3
|
6天前
|
索引 Python
Python NumPy 广播(Broadcast)
Python NumPy 广播(Broadcast)
15 2
|
5天前
|
Python
NumPy 教程 之 Numpy 数组操作 24
本教程介绍Numpy中分割数组的方法,特别是`vsplit`函数,它能将数组沿垂直轴分为多个子数组。示例代码展示了如何使用`vsplit`将一个4x4的数组分为两个2x4的子数组,适用于需要按行分割数据的场景。
8 1
|
7天前
|
Python
NumPy 教程 之 Numpy 数组操作 22
本教程介绍NumPy中分割数组的方法。`numpy.split`可沿指定轴将数组分为子数组,参数包括待分割数组、切分数或位置及轴向。示例展示了如何使用`numpy.split`和`numpy.hsplit`沿不同轴向分割一个4x4数组。`numpy.split`在默认轴0方向分割,而通过设定`axis=1`实现水平分割;`numpy.hsplit`则专门用于水平分割。
16 2
|
2天前
|
数据处理 索引 Python
NumPy 数组操作:和普通操作相较,到底蕴含着怎样令人费解的独特魅力?
【8月更文挑战第19天】NumPy是Python科学计算核心库,提供高效数组操作。不同于Python列表直接列举创建,NumPy用`np.array()`创建数组。两者都支持索引和切片,但NumPy性能更优。数学运算方面,NumPy支持简洁的向量化操作,如`my_array * 2`,无需循环。NumPy还简化了数组形状变换,如使用`reshape()`方法。此外,NumPy数组要求元素类型一致,提高了内存使用效率和计算速度。这些特点使NumPy在科学计算和数据分析中不可或缺。
|
5天前
|
Python
NumPy 教程 之 Numpy 数组操作 25
Numpy 提供多种数组操作函数,如修改形状(`resize`)、翻转、调整维度、连接与分割数组等。还支持元素的增删,例如使用 `append` 添加元素至数组末尾,`insert` 在指定位置插入,`delete` 删除指定元素,以及利用 `unique` 获取数组中的唯一元素。`resize` 可按需调整数组大小,若新大小超过原大小,会复制原有元素以填充。
18 0