Numpy的介绍与使用

一、数组的创建

数组简介
数组 (array) 是相同类型的元素 (element) 的集合所组成数据结构 (data structure)。numpy 数组中的元素用的最多是「数值型」元素,平时我们说的一维、二维、三维数组长下面这个样子 (对应着线、面、体)。四维数组很难被可视化。
在这里插入图片描述
注意一个关键字 axis,中文叫「轴」,一个数组是多少维度就有多少根轴。由于 Python 计数都是从 0 开始的,那么

第 1 维度 = axis 0
第 2 维度 = axis 1
第 3 维度 = axis 2

二、创建数组

带着上面这个对轴的认识,接下来我们用代码来创建 numpy 数组,有三种方式:
步就班的 np.array() 用在列表和元组上
定隔定点的 np.arange() 和 np.linspace()
一步登天的 np.ones(), np.zeros(), np.eye() 和 np.random.random()

按步就班法
给了「列表」和「元组」原材料,用 np.array() 包装一下便得到 numpy 数组。

import numpy as np
l = [3.5, 5, 2, 7, 9]
print(np.array(l))

[3.5 5.  2.  7.  9. ]

定隔定点法
更常见的两种创建 numpy 数组方法:

定隔的 arange:固定元素大小间隔
定点的 linspace:固定元素个数
函数 arange 的参数为起点 , 终点 , 间隔

print(np.arange(8))
print(np.arange(2, 8))
print(np.arange(2, 8, 2))

[0 1 2 3 4 5 6 7]
[2 3 4 5 6 7]
[2 4 6]

函数 linspace 的参数为起点 , 终点 , 点数
linspace (start , stop , num)

其中 start 和 stop 必须要有,num 没有的话默认为 50。对着这个规则看看上面各种情况的输出。

import numpy as np
print(np.linspace(2, 6, 3))             # 均分为三个
t = np.linspace(3, 8, 11)
print(np.linspace(3, 8, 11)

[2. 4. 6.]
[3.  3.5 4.  4.5 5.  5.5 6.  6.5 7.  7.5 8. ]

一步登天法
NumPy 还提供一次性

用 zeros() 创建全是 0 的 n 维数组

用 ones() 创建全是 1 的 n 维数组

用 random() 创建随机 n 维数组

用 eye() 创建对角矩阵 (二维数组)

对于前三种,由于输出是 n 为数组,它们的参数是一个「标量」或「元组类型的形状」,下面三个例子一看就懂了:

print(np.zeros(5))
print(np.ones((2, 3)))
print(np.random.random((2, 3, 4)))

[0. 0. 0. 0. 0.]
[[1. 1. 1.]
 [1. 1. 1.]]
[[[0.22776412 0.72046211 0.29758594 0.0923665 ]
  [0.2027479  0.53507183 0.61219788 0.50821071]
  [0.62908069 0.6038276  0.53519934 0.10484686]]

 [[0.20239382 0.34965616 0.22142288 0.56592552]
  [0.32693076 0.09853307 0.49262424 0.96626366]
  [0.4547175  0.63994587 0.2033189  0.40908813]]]

对于函数 eye(),它的参数就是一个标量,控制矩阵的行数或列数:

此外还可以设定 eye() 里面的参数 k

默认设置 k = 0 代表 1 落在对角线上

k = 1 代表 1 落在对角线右上方

k = -1 代表 1 落在对角线左下方

np.eye(4)
print(np.eye(4, k=1))
np.eye(4, k=-1)

[[0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]
 [0. 0. 0. 0.]]


rray([[0., 0., 0., 0.],
       [1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.]])

三、 数组的性质

一维数组
用按步就班的 np.array() 带列表生成数组 arr

现在你应该会用 dir(arr) 来查看数组的属性了吧,看完之后我们对 type, ndim, len(), size, shape, stride, dtype 几个感兴趣,一一打印出来看看:

arr = np.array([3.5, 5, 2, 8, 4.2])
print('The type is:', type(arr))
print('The dimension is:', arr.ndim)
print('The length is:', len(arr))
print('The number of elements is:', arr.size)
print('The shape of array is:', arr.shape)
print('The stride of array is:', arr.strides)
print('The type of elements is:', arr.dtype)

The type is: <class 'numpy.ndarray'>
The dimension is: 1
The length is: 5
The number of elements is: 5
The shape of array is: (5,)
The stride of array is: (8,)
The type of elements is: float64

根据结果我们来看看上面属性到底是啥:

type:数组类型,当然是 numpy.ndarray

ndim:维度个数是 1

len():数组长度为 5 (注意这个说法只对一维数组有意义)

size:数组元素个数为 5

shape:数组形状,即每个维度的元素个数 (用元组来表示),只有一维,元素个数为 5,写成元组形式是 (5,)

strides:跨度,即在某一维度下为了获取到下一个元素需要「跨过」的字节数 (用元组来表示),float64 是 8 个字节数 (bytes),因此跨度为 8

dtype:数组元素类型,是双精度浮点 (注意和 type 区分)

注意我黄色高亮了 strides,这个概念对于解决引言的「转置高维数组」问题很重要。一图胜千言。在这里插入图片描述

四、二维数组

先用按步就班的 np.array() 带二维列表生成二维数组 arr2d按步就班的 np.array() 带二维列表生成二维数组 arr2d

l2 = [[1, 2, 3], [4, 5, 6]]
arr2d = np.array(l2)
arr2d

array([[1, 2, 3],
       [4, 5, 6]])

print("The typeis :", type(arr2d))
print("The dimension is:", arr2d.ndim)
print("The length of array is:", len(arr2d))
print("The number of elments is:", arr2d.size)
print("The shape of array is:", arr2d.shape)
print("The stride of array is:", arr2d.strides)
print("The type of elements is:", arr2d.dtype)

The typeis : <class 'numpy.ndarray'>
The dimension is: 2
The length of array is: 2
The number of elments is: 6
The shape of array is: (2, 3)
The stride of array is: (12, 4)
The type of elements is: int32

同样,我们来分析一下上面属性:

type:数组类型 numpy.ndarray

ndim:维度个数是 2

len():数组长度为 2 (严格定义 len 是数组在「轴 0」的元素个数)

size:数组元素个数为 6

shape:数组形状 (2, 3)

strides:跨度 (12, 4) 看完下图再解释

dtype:数组元素类型 int32

对于二维数组,Python 视图」看它和「内存块」存储它的形式是不一样的,如下图所示:
在这里插入图片描述
n 维数组
我们使用np.random.random()来生成一个多维数组

arr4d = np.random.random((2, 2, 2, 3))

print("The type is:", type(arr4d))
print("The dimension is:", arr4d.ndim)
print("The length of array is:", len(arr4d))
print("The number of elments is:", arr4d.size)
print("The shape of array is:", arr4d.shape)
print("The stride of array is:", arr4d.strides)
print("The type of elments is:", arr4d.dtype)
arr4d

The type is: <class 'numpy.ndarray'>
The dimension is: 4
The length of array is: 2
The number of elments is: 24
The shape of array is: (2, 2, 2, 3)
The stride of array is: (96, 48, 24, 8)
The type of elments is: float64


array([[[[0.12097602, 0.85898477, 0.16043155],
         [0.87946725, 0.96358488, 0.4051294 ]],

        [[0.65434255, 0.21199418, 0.68517886],
         [0.53783086, 0.93971496, 0.14067768]]],


       [[[0.93745553, 0.95048614, 0.81013165],
         [0.36328647, 0.16424842, 0.96708327]],

        [[0.90332958, 0.30356389, 0.50146022],
         [0.05044289, 0.49204122, 0.2607904 ]]]])

数组的获取
获取数组是通过索引 (indexing) 和切片 (slicing) 来完成的,

切片是获取一段特定位置的元素

索引是获取一个特定位置的元素

索引和切片的方式和列表一模一样。对于一维数组 arr,

切片写法是 arr[start : stop : step]

索引写法是 arr[index]

因此,切片的操作是可以用索引操作来实现的 (一个一个总能凑成一段),只是没必要罢了。为了简化,我们在本章三节标题里把切片和索引都叫做索引。

索引数组有三种形式,正规索引 (normal indexing)、布尔索引 (boolean indexing) 和花式索引 (fancy indexing)。

正规索引
虽然切片操作可以由多次索引操作替代,但两者最大的区别在于

切片得到的是原数组的一个视图 (view) ,修改切片中的内容会改变原数组

索引得到的是原数组的一个复制 (copy),修改索引中的内容不会改变原数组

请看下面一维数组的例子来说明上述两者的不同。

一维数组

arr = np.arange(10)
arr

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

二维数组

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值