numpy
Python的list数据结构与numpy的array数据结构差别
list中的数据可以不同类型的数据,但array中必须是同构的数据结构
numpy比list更快,numpy使用更少的内存占用来存储数据,并提供了指明数据类型的机制。这让代码优化更进一步。
array是什么
array是numpy重要的数据结构。array是一个数值网格,它包含着原始数据的信息,如何定位一个元素,以及如何解析一个元素。它的元素网格可以通过多种方式进行索引。元素都是同一类型,被称为array的dtype(data type)
array可以通过很多方式进行索引,包括非负整数的元组,布尔值,另一个array或整数。array的rank(秩)是数组维度的数量。shape是一个整数组成的元组,给出了array沿着每个维度的size大小。
一种初始化numpy arrays的方式是从Python lists创建,使用嵌套列表来生成二维以及更高维度的数据。
a = np.array([1,2,3,4,5,6])
a.shape (6,)
a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
a.shape (3, 4)
可以使用方括号访问array数组的元素。当你访问元素,记得numpy的索引从0开始计算。这意味着如果要访问第一个元素,要用下标0
print(a[0])
[1,2,3,4]
更多关于arrays的信息
这部分覆盖了一维array,2维array,ndarray,vector,matrix
你可能听过一个被称为ndarray的array,是‘n维array’的缩写。一个N维数组简单来说是一个可以是任意维度的数组。你可能也听过1-D(一维)或1维数组,2-D或二维数组。numpy中的ndarray既可以表示矩阵也可以表示向量。一个vector(向量)是只有一维的array(行向量和列向量没有区别),而一个matrix(矩阵)表示具有两个维度的array。3-D(三维)及更高维度的array,经常用术语tensor(张量)来表示。
array数组有什么属性
一个array数组经常是用作一个大小固定的容器,其中的元素具有相同的数据类型和大小。array中的维度数量和元素数量已经被其shape定义了。一个array的shape是一个非负整数组成的元组,指定了每个维度上的大小。
在numpy中,维度被称为axes(坐标轴)。这意味这如果有一个2位数组像这样
[[0.,0.,0.],
[1.,1.,1.]]
这个array有两个axes(坐标轴)。第一个axes长度为2,第二个axes长度为3。(2行3列的数据/矩阵)
像其他Python容器对象一样,array的内容可以通过索引或数组切片被访问或修改。不像典型的容器对象,不同数组可以共享相同数据,所以某个array上的修改可能被另一个array可见。
array的属性反应了array内在的信息。如果你需要get,set数组的属性,不需要重新创建一个array,可以通过属性访问一个array。
如何创建一个基础array
这部分包含np.array(),np.zeros(),np.ones(),np.empty(),np.arange(),np.linsapce(),dtype
创建一个numpy的array,可以使用函数np.array()
所需做的就是传递一个list给array。如果需要,还可以指定list数据的数据类型。
import numpy as np
a = np.array([1,2,3])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dye1MvBS-1691137027881)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c17b529a-6087-43ca-a402-99306a5ed266/Untitled.png)]
请注意这些可视化信息是为了简化概念以及给你一个numpy概念和构成的基本理解。数组和数组的操作比这里展示的复杂的多。
除了创建一系列元素的array,还可以很容易地创建填充满0的array
np.zeros(2)
array([0.,0.])
或填充满1的array
np.ones(2)
array([1.,1.])
甚至是空array。函数empty创建一个array,其中初始化内容是随机的,完全依赖于内存当时的状态。使用empty而不是zeros(或类似函数)的原因是速度快,确认是否需要以初始值填充每一个元素值。
np.empty(2)
array([3.14, 42. ]) # may vary
可以创建一个array包含一个range范围内的值
np.arange(4)
array([0,1,2,3])
甚至可以包含等间距间隔的数据。需要指定第一个数字,最后一个数字以及间隔的大小step size。
np.arange(2, 9, 2)
array([2,4,6,8])
np.linspace()创建一个数组以特定的间隔间隔开的数据
np.linspace(0, 10, num=5)
array([ 0. , 2.5, 5. , 7.5, 10. ])
指定数据类型
默认的数据类型是浮点数np.float64,你可以通过dtype关键字指定数据类型
x = np.ones(2, dtype=np.int64)
x
array([1,1])
添加,删除和排序元素
这部分覆盖了np.sosrt()和np.concatenate()
使用np.sort()排序元素很简单。你可以指定axis坐标轴,kind和order。
arr = np.array([2,1,5,3,7,4,6,8])
np.sort(arr)
对于sort函数,它返回是array的一份拷贝,你可以使用
argsort:沿着指定轴的间接排序
lexsort:对多个键进行间接稳定排序
searchsorted:查找已排序数组中的元素
partition:部分排序
如果使用以下数组
a = np.array([1,2,3,4])
b = np.array([5,6,7,8])
可以使用np.concatenate()函数连接2个数组
如果从以下数组出发
x = np.array([[1,2],[3,4]])
y = np.array([[5,6]])
axis(轴)与数组括号的对应关系
numpy数组都有[]标记,其对应关系:
axis=0对应最外层的[]
axis=1对应第二外层的[]
axis=n对应第n外层的[]
以三维数组为例,两者关系如下表所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KjCMHN0k-1691137027882)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/db539c3a-b9a0-4c41-96f2-4316202afd9b/Untitled.png)]
np.concatenate((x,y),axis=0)
array([[1,2],
[3,4],
[5,6]])
为了从array中移除元素,很容易通过index来选择数组中希望保留的元素。
如何知道一个array的shape和size
这部分会覆盖ndarray.ndim,ndarray.size,ndarray.shape
ndarray.ndim将告诉你axes坐标轴的数量或数组的维度
ndarray.size会告诉你数组中元素的总个数。这是数组元素shape的乘积。
ndarray.shape将展示一个整数元组,代表着数组沿着每个维度分别存储的元素数量。比如你有一个2行3列的2维数组,shape就是(2,3)
array_example = np.array([[[0, 1, 2, 3],
[4, 5, 6, 7]],
[[0, 1, 2, 3],
[4, 5, 6, 7]],
[[0 ,1 ,2, 3],
[4, 5, 6, 7]]])
获取array的维度
array_example.ndim
3
获取array的元素总数
array_example.size
24
获取array的shape
array_example.shape
(3,2,4)
可以使用reshape修改形状
使用reshape()将给出一个新的shape,array不会改变已有数据的值。
需要记住的是,当你reshape一个array时,你想生成的array需要和原始array有相同数量的元素。如果数组最开始有12个元素,要明确你的新数组也将有总共12个元素。
如果数组起始时是:
a = np.arange(6)
print(a)
可以使用reshape()函数来reshape你的数组。比如,你可以reshape这个数组到另一个具有3行2列的数组
b = a.reshape(3, 2)
print(b)
[[0 1]
[2 3]
[4 5]]
对于np.reshape,可以指定一些可选参数
np.reshape(a, newshape=(1,6), order='C')
newshape是要指定的新的shape。需要指定一个整数或者整数元组。
order: C意味着读写元素使用类C的索引顺序,F意味着读写元素使用类Fortran的索引顺序,A意味着读写元素当a是内存中连续的Fortran时用类Fortran索引顺序,其他时候用类C的顺序。
如何将一个一维数组转换为2维数组(如何为array添加新轴axis)
这部分涵盖np.newaxis,np.expand_dims
可以使用np.newaxis和np.expand_dims为已存在的array增加维度
使用np.newaxis每次都将为你的数组增加一个维度。这意味着一维数据将变成二维数组,一个二维数组将变成3维数组,以此类推。
如果最开始的数组是这样的
a = np.array([1,2,3,4,5,6])
a.shape
(6,)
使用np.newaxis来添加一个新的axis
a2=a[np.newaxis, :]
a2.shape
(1, 6)
你可以明确地用np.newaxis转换一个一维数组地一个行向量或者一个列向量。例如,你可以转换1个一维数组至行向量,通过沿着第一个维度插入一个axis轴,如下:
row_vector = a[np.newaxis, :]
row_vector.shape
(1,6)
你也可以使用np.expand_dims在一个指定的位置上插入一个axis
a = np.array([1,2,3,4,5,6])
a.shape
(6,)
通过np.expand_dims来在索引位置1添加一个axis
b = np.expand_dims(a, axis=1)
b.shape
(6,1)
添加一个轴在索引位置0
c = np.expand_dims(a, axis=0)
c.shape
(1, 6)
索引和切片
你可以像操作Python lists一样, 操作numpy的arrays
data = np.array([1, 2, 3])
data[1]
2
data[0:2]
array([1, 2])
data[1:]
array([2, 3])
data[-2:]
array([2, 3])
如果您想从数组中选择满足某些条件的值,使用NumPy很简单。
比如,最初的array如下
a = np.array([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
打印array中小于5的值
print(a[a<5])
[1 2 3 4]
也可以选择大于等于5的值
a[a>=5]
array([ 5, 6, 7, 8, 9, 10, 11, 12])
如何从已存在的数据中创建array
这部分涵盖slicing and indexing,np.vstack(),np.hstack(),np.hsplit(),.view(),copy()
可以很轻松地从已有数组中创建出一个新数组
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
arr1 = a[3:8]
arr1
array([4, 5, 6, 7, 8])
你也可以堆叠2个已存在的数组,既可以垂直堆叠也可以水平堆叠。
比如最初有两个数组,a1,a2
a1 = np.array([[1, 1],
[2, 2]])
a2 = np.array([[3, 3],
[4, 4]])
你可以用vstack垂直堆叠它们
np.vstack((a1, a2))
array([[1, 1],
[2, 2],
[3, 3],
[4, 4]])
或者使用hstack水平堆叠它们
np.hstack((a1, a2))
array([[1, 1, 3, 3],
[2, 2, 4, 4]])
你可以使用hsplit函数分割一个数组成为多个小数组。你可以指定要返回的等形数组的数量,也可以指定要进行除法的列。
例如最初的数组如下
x = np.arange(1, 25).reshape(2, 12)
x
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
[13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]])
如果希望将这个数组分割成3个等形状的数组,可以这样执行
np.hsplit(x, 3)
[array([[ 1, 2, 3, 4],
[13, 14, 15, 16]]),
array([[ 5, 6, 7, 8],
[17, 18, 19, 20]]),
array([[ 9, 10, 11, 12],
[21, 22, 23, 24]])]
如果希望希望在第三和第四列后分割,可以这样运行
np.hsplit(x, (3, 4))
[array([[ 1, 2, 3],
[13, 14, 15]]), array([[ 4],
[16]]), array([[ 5, 6, 7, 8, 9, 10, 11, 12],
[17, 18, 19, 20, 21, 22, 23, 24]])]
可以使用view函数创建一个新数组对象,看起来像是原数组(一个影子拷贝)
views是一个重要的numpy的概念。numpy函数,也即操作,例如索引和分片,将返回views只要可能的话。这会节省内存并且快速运行(不需要拷贝数据)。然而,需要知道的重要的一点是,在view中修改数据,也会修改原始的array的!
创建一个数组
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
然后创建一个数组b1通过对a进行分片操作,并修改其第一个元素。这也会修改a中对应的元素
b1 = a[0, :]
b1
array([1, 2, 3, 4])
b1[0] = 99
b1
array([99, 2, 3, 4])
a
array([[99, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
使用copy函数会创建一个数组的完整拷贝,包含其数据(深拷贝)。可以这样使用
b2 = a.copy()
数组的基本操作
这部分包含加法,剑法,乘法,除法等
一旦你已经创建了数组,你可以开始使用它们。比如,创建了2个数组,一个称为data,一个称为ones
data = np.array([1, 2])
ones = np.ones(2, dtype=int)
data + ones
array([2, 3])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WgjvYaXh-1691137027883)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b630c89c-b88a-49c3-9428-9838a5199a66/Untitled.png)]
可以做的操作不只是加法
data - ones
array([0, 1])
data * data
array([1, 4])
data / data
array([1., 1.])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NzlULVFK-1691137027883)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/371c3ed3-041b-4924-8783-e8550910dc06/Untitled.png)]
numpy的基础操作都很简单。如果你希望得到数组中所有元素的和,你可以使用sum()函数。这在一维数组,二维数组和高维数组中都可以使用。
起始时数组时
b = np.array([[1,1], [2,2]])
如果要求行轴上的和
b.sum(axis=0)
array([3,3])
求列轴上的和
b.sum(axis=1)
array([2,4])
广播
有时可能需要在数组和单个数字之间执行操作,(也称为向量与矢量间的操作)或在两个大小不同的数组间操作。例如,你的数组(称之为数据)可能包含以英里为单位的举例,但你想转换这些信息到千米。你可以做如下操作
data = np.array([1.0, 2.0])
data * 1.6
array([1.6, 3.2])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XhY0gzdP-1691137027883)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/841d46e4-f1e8-40e1-8f23-db4222d7d44c/Untitled.png)]
numpy能理解乘法操作应该在每个cell上都要执行。这个概念称为广播。广播的机制允许numpy在不同的shape上做操作。数组的维度必须是兼容的,例如,当两个数组的维度相同或者其中一个为1时,如果维度不兼容,会得到ValueError的报错。
其他有用的数组操作
这部分涵盖最大值,最小值,求和,均值,乘法,标准差及其他相关操作
numpy允许聚合操作。除了min,max和sum,你也能轻松执行mean获取平均值,prod获取所有元素乘积的结果,std获取标准差等
data.max()
2.0
data.min()
1.0
data.sum()
3.0
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gAUEiEZ2-1691137027884)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4fc5216e-2b81-4eac-9c47-ac44428cb2b3/Untitled.png)]
设置一个数组,为a
a = np.array([[0.45053314, 0.17296777, 0.34376245, 0.5510652],
[0.54627315, 0.05093587, 0.40067661, 0.55645993],
[0.12697628, 0.82485143, 0.26590556, 0.56917101]])
非常普遍的是沿着某行或列进行聚合。默认情况下,每个numpy聚合函数都会返回整个数组的聚合结果。
你可以指定某一个你希望计算聚合值的轴。比如,你可以通过指定axis=0来找出每一列上的最小值
a.min(axis=0)
array([0.12697628, 0.05093587, 0.26590556, 0.5510652 ])
创建矩阵
你可以通过传递Python lists来创建二维数组(或矩阵)在numpy中表示它们。
data = np.array([[1,2], [3,4], [5,6]])
data
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Un4zEicZ-1691137027884)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c988f980-4ae5-4e85-9593-b4c1f9551cda/Untitled.png)]
当你操作矩阵时,索引和分片操作是很有用的。
data[0, 1]
2
data[1:3]
array([[3, 4],
[5, 6]])
data[0:2, 0]
array([1, 3])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yz2VAFYK-1691137027884)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4ab91904-487d-4e8b-893e-88334bb5284f/Untitled.png)]
data.max()
6
>>> data.min()
1
>>> data.sum()
21
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VlUOxcZL-1691137027884)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d2d6cffc-f370-4e08-b056-3165980211a4/Untitled.png)]
你可以聚合矩阵中所有的值,也可以使用axis参数来以行或列的形式聚合它们。为了说明这点,让我们看一个稍微修改过的数据集。
data = np.array([[1, 2], [5, 3], [4, 6]])
data
array([[1, 2],
[5, 3],
[4, 6]])
data.max(axis=0)
array([5, 6])
data.max(axis=1)
array([2, 5, 6])
一旦你创建了你的矩阵,你可以使用算术运算符对他们进行相加或相乘的操作,如果这两个矩阵是相同size的话。
data = np.array([[1, 2], [3, 4]])
ones = np.array([[1, 1], [1, 1]])
data + ones
array([[2, 3],
[4, 5]])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4QFjSRa6-1691137027885)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ea7c7739-e696-4a32-b6cd-d6a83c6cb8c9/Untitled.png)]
你可以对一些大小不同的矩阵做一些操作,但只有当其中一个矩阵只有一行或一列的情况下。在这种情况下,numpy将会使用广播规则进行该操作。
data = np.array([[1, 2], [3, 4], [5, 6]])
ones_row = np.array([[1, 1]])
data + ones_row
array([[2, 3],
[4, 5],
[6, 7]])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGVpdq04-1691137027885)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a9bff327-c3a9-4dcf-9f12-cf44ab5810cb/Untitled.png)]
注意,当NumPy打印n维数组时,最后一个轴的循环速度最快,而第一个轴的循环速度最慢。例如:
np.ones((4, 3, 2))
array([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])
通常情况下,我们希望NumPy初始化数组的值。numpy提供了ones(),zeros()以及random.Generator类来生成随机数。你需要做的就是传入你希望它生成的数量。
np.ones(3)
array([1., 1., 1.])
np.zeros(3)
array([0., 0., 0.])
rng = np.random.default_rng()
rng.random(13)
array([0.15373629, 0.69898599, 0.77647242])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KR5ou0G-1691137027885)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3841c017-374c-4c7d-858a-51a0720ad0ae/Untitled.png)]
你可以使用ones(),zeros(),random()来创建二维数组,如果传参时你提供一个元组来描述矩阵的维度。
np.ones((3, 2))
array([[1., 1.],
[1., 1.],
[1., 1.]])
np.zeros((3, 2))
array([[0., 0.],
[0., 0.],
[0., 0.]])
rng.random((3, 2))
array([[0.01652764, 0.81327024],
[0.91275558, 0.60663578],
[0.72949656, 0.54362499]]) # may vary
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AJ3R4G54-1691137027885)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/217407b8-7961-45a2-91d3-a4e6d4c0bcdf/Untitled.png)]
生成随机数字
生成随机数字的使用是配置和评估需要数学和机器学习算法的关键部分。无论你是需要在人工神经网络中随机初始化权重,将数据分成随机集,还是随机洗牌数据集,都必须能够生成随机数(实际上是可重复的伪随机数)。
通过Genrator.integers,您可以生成从低到高(前闭后开区间)的随机整数。你可以通过设置endpoint=True使得区间变成前闭后闭区间。
你可以生成一个2行4列由0-4之间的随机整数组成的数组。
rng.integers(5, size=(2, 4))
array([[2, 1, 1, 0],
[0, 0, 0, 4]]) # may vary
如何获取去重的元素和数量
这部分涵盖np.unique()
你可以使用np.unique从数组中找去重的元素。
例如,起始数组如下
a = np.array([11, 11, 12, 13, 14, 15, 16, 17, 12, 13, 11, 14, 18, 19, 20])
使用np.unique打印数组中去重后的值
unique_values = np.unique(a)
print(unique_values)
[11 12 13 14 15 16 17 18 19 20]
要获得NumPy数组中唯一值的索引(数组中唯一值的第一个索引位置的数组),只需在np.unique()中传递return_index参数以及您的数组。
unique_values, indices_list = np.unique(a, return_index=True)
print(indices_list)
[ 0 2 3 4 5 6 7 12 13 14]
可以通过传递return_counts参数来获取唯一值在numpy数组出现的次数
unique_values, occurrence_count = np.unique(a, return_counts=True)
print(occurrence_count)
[3 2 2 2 1 1 1 1 1 1]
这在二维数据中同样起作用。如果起初数组是这样
a_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [1, 2, 3, 4]])
可以找到唯一值
unique_values = np.unique(a_2d)
print(unique_values)
[ 1 2 3 4 5 6 7 8 9 10 11 12]
如果未传递axis参数,则二维数组将被平面化。如果希望获得唯一的行或列,请确保传递axis参数。要查找唯一的行,请指定axis=0,对于列,请指定axis=1。
unique_rows = np.unique(a_2d, axis=0)
print(unique_rows)
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
要获取唯一行、索引位置和出现次数,您可以使用:
unique_rows, indices, occurrence_count = np.unique(
a_2d, axis=0, return_counts=True, return_index=True)
print(unique_rows)
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
print(indices)
[0 1 2]
print(occurrence_count)
[2 1 1]
转置和整形一个矩阵
这部分涵盖arr.reshape(),arr.transpose(),arr.T
通常需要对矩阵进行转置。NumPy数组有一个属性T,它允许你对矩阵进行转置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8r3zRsrQ-1691137027885)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b5b032af-c991-4ce7-991e-b3a7baefa2c8/Untitled.png)]
你可能还需要变换矩阵的维数。例如,当您有一个模型期望与您的数据集不同的特定输入形状时,就会发生这种情况。这就是reshape方法可以发挥作用的地方。你只需要传入你想要的矩阵的新维度。
data.reshape(2, 3)
array([[1, 2, 3],
[4, 5, 6]])
data.reshape(3, 2)
array([[1, 2],
[3, 4],
[5, 6]])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TDcjGhEk-1691137027886)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d6fd0746-3f51-47a7-a407-18ab95b762b6/Untitled.png)]
您还可以根据指定的值使用.transpose()来反转或更改数组的轴。
起始矩阵如下
arr = np.arange(6).reshape((2, 3))
arr
array([[0, 1, 2],
[3, 4, 5]])
您可以使用arr.transpose()对数组进行转置。
arr.transpose()
array([[0, 3],
[1, 4],
[2, 5]])
你也可以使用arr.T来实现
arr.T
array([[0, 3],
[1, 4],
[2, 5]])
如何反转一个矩阵
这部分涵盖np.flip()
numpy的np.flip()函数允许你flip或者reverse,在数组中沿着一个轴的内容。当你使用np.flip(),指定你希望reverse的数组以及轴axis。如果你不指定axis轴,numpy将沿着所有axes轴翻转内容。
反转一维数组
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
reversed_arr = np.flip(arr)
print('Reversed Array: ', reversed_arr)
Reversed Array: [8 7 6 5 4 3 2 1]
反转二维数组
arr_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
reversed_arr = np.flip(arr_2d)
print(reversed_arr)
[[12 11 10 9]
[ 8 7 6 5]
[ 4 3 2 1]]
你可以很容易地只反转行
reversed_arr_rows = np.flip(arr_2d, axis=0)
print(reversed_arr_rows)
[[ 9 10 11 12]
[ 5 6 7 8]
[ 1 2 3 4]]
或者只是反转列
reversed_arr_columns = np.flip(arr_2d, axis=1)
print(reversed_arr_columns)
[[ 4 3 2 1]
[ 8 7 6 5]
[12 11 10 9]]
你也可以只反转一行或一列,你可以反转索引位置为1地行的数据
arr_2d[1] = np.flip(arr_2d[1])
print(arr_2d)
[[ 1 2 3 4]
[ 8 7 6 5]
[ 9 10 11 12]]
你也可以反转索引位置为1的列
arr_2d[:,1] = np.flip(arr_2d[:,1])
print(arr_2d)
[[ 1 10 3 4]
[ 8 7 6 5]
[ 9 2 11 12]]
重塑和平面化多维数组
这部分涵盖flatten(),ravel()
有两种常用的方法来扁平化数组:.flatten()和.ravel()。两者之间的主要区别在于,使用ravel()创建的新数组实际上是对父数组的引用(即“视图”)。这意味着对新数组的任何更改也将影响父数组。因为ravel不创建副本,所以它的内存效率很高。
x = np.array([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
可以使用flatten将数组转换为一维数据
x.flatten()
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
当你使用flatten,对新数组的改变不会影响原始数组
a1 = x.flatten()
a1[0] = 99
print(x) # Original array
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
print(a1) # New array
[99 2 3 4 5 6 7 8 9 10 11 12]
但是当你使用ravel,对新数组的变化是会影响原数组的
a2 = x.ravel()
a2[0] = 98
print(x) # Original array
[[98 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
print(a2) # New array
[98 2 3 4 5 6 7 8 9 10 11 12]
如何访问文档字符串来获取更多信息
这部分包括help(),?和??
当涉及到数据科学生态系统时,Python和NumPy是在考虑用户的情况下构建的。最好的例子之一就是内置的文档访问。每个对象都包含对字符串的引用,该字符串称为docstring。在大多数情况下,这个文档字符串包含对象的快速和简洁的摘要以及如何使用它。Python有一个内置的help()函数可以帮助您访问这些信息。这意味着几乎在任何需要更多信息的时候,都可以使用help()快速找到所需的信息。
例如:
help(max)
Help on built-in function max in module builtins:
max(...)
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value
With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.
因为访问附加信息非常有用,所以IPython使用?字符作为访问此文档以及其他相关信息的简写。IPython是一个用于多种语言交互计算的命令shell。
您甚至可以将这种符号用于对象方法和对象本身。
max?
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value
With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.
Type: builtin_function_or_method
a = np.array([1, 2, 3, 4, 5, 6])
然后你可以获得很多有用的信息(首先是关于a本身的细节,然后是a是其实例的narray的docstring):
a?
Type: ndarray
String form: [1 2 3 4 5 6]
Length: 6
File: ~/anaconda3/lib/python3.9/site-packages/numpy/__init__.py
Docstring: <no docstring>
Class docstring:
ndarray(shape, dtype=float, buffer=None, offset=0,
strides=None, order=None)
An array object represents a multidimensional, homogeneous array
of fixed-size items. An associated data-type object describes the
format of each element in the array (its byte-order, how many bytes it
occupies in memory, whether it is an integer, a floating point number,
or something else, etc.)
Arrays should be constructed using `array`, `zeros` or `empty` (refer
to the See Also section below). The parameters given here refer to
a low-level method (`ndarray(...)`) for instantiating an array.
For more information, refer to the `numpy` module and examine the
methods and attributes of an array.
Parameters
----------
(for the __new__ method; see Notes below)
shape : tuple of ints
Shape of created array.
...
这也适用于您创建的函数和其他对象。只要记住在函数中包含一个文档字符串,使用字符串字面值(在文档周围使用"“” “”"或’‘’ ‘’')。
例如定义一个函数
def double(a):
'''Return a * 2'''
return a * 2
double?
Signature: double(a)
Docstring: Return a * 2
File: ~/Desktop/<ipython-input-23-b5adf20be596>
Type: function
通过阅读感兴趣的对象的源代码,您可以获得另一个层次的信息。使用双问号(??)允许您访问源代码。
例如:
double??
Signature: double(a)
Source:
def double(a):
'''Return a * 2'''
return a * 2
File: ~/Desktop/<ipython-input-23-b5adf20be596>
Type: function
如果对象是用Python以外的语言编译的,使用??返回与?相同的信息。你会在很多内置对象和类型中发现这一点,例如:
len?
Signature: len(obj, /)
Docstring: Return the number of items in a container.
Type: builtin_function_or_method
len??
Signature: len(obj, /)
Docstring: Return the number of items in a container.
Type: builtin_function_or_method
有相同的输出,因为它们是用Python以外的编程语言编译的。
使用数学公式
在数组上实现数学公式的便利性是NumPy在科学Python社区中广泛使用的原因之一。
例如,这是均方误差公式(用于处理回归的监督机器学习模型的中心公式):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5giRRi5e-1691137027886)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3ad18af4-7319-4c44-bf7c-02875ab6c7b6/Untitled.png)]
在NumPy中实现这个公式是简单直接的:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-530Ixsx2-1691137027886)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/bddc2f0e-827f-4286-8aab-c365e732068b/Untitled.png)]
这种方法之所以有效,是因为预测和标签可以包含一个或一千个值。他们只需要是相同的大小。
你可以这样想象:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-65iipuST-1691137027886)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/36a2b694-406b-4c1e-9c6b-fb57ca1c4d85/Untitled.png)]
在本例中,预测向量和标签向量都包含三个值,这意味着n的值为3。在我们做减法之后,向量中的值是平方的。然后NumPy对这些值求和,结果是该预测的误差值和模型质量的分数。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Tuitp46-1691137027886)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d0f30102-fb5c-4c3c-80b6-4cee22e90ddd/Untitled.png)]
如何保存和加载numpy对象
这部分涵盖np.save,np.savez,np.savetxt,np.load,np.loadtxt
在某些情况下,您可能希望将数组保存到磁盘上并将其加载回来,而不必重新运行代码。幸运的是,有几种方法可以用NumPy保存和加载对象。narray对象可以通过loadtxt和savetext函数保存和加载到磁盘文件中,这些函数用于处理普通文本文件,load和save函数用于处理扩展名为.npy的NumPy二进制文件,savez函数用于处理扩展名为.npz的NumPy文件。
.npy和.npz文件存储重构narray所需的数据、形状、dtype和其他信息,以便能够正确检索数组,即使文件位于具有不同体系结构的另一台机器上也是如此。
如果你想存储单个nd`array对象,使用np.save将其存储为.npy文件。如果您想在单个文件中存储多个narray对象,请使用np.savez将其保存为.npz文件。还可以使用savez_compressed将多个数组以压缩的npz格式保存到一个文件中。
使用np.save()很容易保存和加载数组。只需确保指定要保存的数组和文件名。例如,如果你创建了这个数组:
a = np.array([1, 2, 3, 4, 5, 6])
你可以保存为filename.npy
np.save('filename', a)
可以使用np.load()函数重建array对象
b = np.load('filename.npy')
您可以使用np. savetext将NumPy数组保存为纯文本文件,如.csv或.txt文件
例如,你创建一个数组
csv_arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
保存成csv文件
np.savetxt('new_file.csv', csv_arr)
从保存地text文件加载对象,使用loadtxt()
np.loadtxt('new_file.csv')
savetext()和loadtxt()函数接受额外的可选参数,如header、footer和分隔符。虽然文本文件更易于共享,但.npy和.npz文件更小,读取速度更快。如果需要对文本文件进行更复杂的处理(例如,如果需要处理包含缺失值的行),则需要使用genfromtxt函数。
使用savetext,您可以指定页眉、页脚、注释等。
导入和导出一个CSV文件
在包含现有信息的CSV中读取很简单。最好和最简单的方法是使用Pandas。
使用Matplotlib绘制数组
如果您需要为您的值生成一个图,使用Matplotlib非常简单。