13.输出杨辉三角行的第1至第10行数据。_从零开始学数据分析第05课:NumPy的应用-2...

数组对象的属性

  • size属性:数组元素

代码:

array19 = np.arange(1, 100, 2)
array20 = np.random.rand(3, 4)
print(array19.size, array20.size)

输出:

50 12
  • shape属性:数组的形状

代码:

print(array19.shape, array20.shape)

输出:

(50,) (3, 4)
  • dtype属性:数组元素的数据类型

代码:

print(array19.dtype, array20.dtype)

输出:

int64 float64

ndarray对象元素的数据类型可以参考如下所示的表格。

e05031d6a440be251e2f669dfb945961.png
  • ndim属性:数组的维度

代码:

print(array19.ndim, array20.ndim)

输出:

1 2
  • itemsize属性:数组单个元素占用内存空间的字节数

代码:

array21 = np.arange(1, 100, 2, dtype=np.int8)
print(array19.itemsize, array20.itemsize, array21.itemsize)

输出:

8 8 1
说明:在使用 arange创建数组对象时,通过 dtype参数指定元素的数据类型。可以看出, np.int8代表的是8位有符号整数,只占用1个字节的内存空间,取值范围是​
equation?tex=%5B-128%2C127%5D
  • nbytes属性:数组所有元素占用内存空间的字节数

代码:

print(array19.nbytes, array20.nbytes, array21.nbytes)

输出:

400 96 50
  • flat属性:数组(一维化之后)元素的迭代器

代码:

from typing import Iterable

print(isinstance(array20.flat, np.ndarray), isinstance(array20.flat, Iterable))

输出:

False True
  • base属性:数组的基对象(如果数组共享了其他数组的内存空间)

代码:

array22 = array19[:]
print(array22.base is array19, array22.base is array21)

输出:

True False
说明: 上面的代码用到了数组的切片操作,它类似于Python中 list类型的切片,但在细节上又不完全相同,下面会专门讲解这个知识点。通过上面的代码可以发现, ndarray切片后得到的新的数组对象跟原来的数组对象共享了内存中的数据,因此 array22base属性就是 array19对应的数组对象。

数组的索引和切片

和Python中的列表类似,NumPy的ndarray对象可以进行索引和切片操作,通过索引可以获取或修改数组中的元素,通过切片可以取出数组的一部分。

  • 索引运算(普通索引)

代码:

array23 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(array23[0], array23[array23.size - 1])
print(array23[-array23.size], array23[-1])

输出:

1 9
1 9

代码:

array24 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(array24[2])
print(array24[0][0], array24[-1][-1])
print(array24[1][1], array24[1, 1])

输出:

[7 8 9]
1 9
5 5

代码:

array24[1][1] = 10
print(array24)
array24[1] = [10, 11, 12]
print(array24)

输出:

[[ 1  2  3]
 [ 4 10  6]
 [ 7  8  9]]
[[ 1  2  3]
 [10 11 12]
 [ 7  8  9]]
  • 切片运算(切片索引)

切片是形如[开始索引:结束索引:步长]的语法,通过指定开始索引(默认值无穷小)、结束索引(默认值无穷大)和步长(默认值1),从数组中取出指定部分的元素并构成新的数组。因为开始索引、结束索引和步长都有默认值,所以它们都可以省略,如果不指定步长,第二个冒号也可以省略。一维数组的切片运算跟Python中的list类型的切片非常类似,此处不再赘述,二维数组的切片可以参考下面的代码,相信非常容易理解。

代码:

print(array24[:2, 1:])

输出:

[[2 3]
 [5 6]]

代码:

print(array24[2])
print(array24[2, :])

输出:

[7 8 9]
[7 8 9]

代码:

print(array24[2:, :])

输出:

[[7 8 9]]

代码:

print(array24[:, :2])

输出:

[[1 2]
 [4 5]
 [7 8]]

代码:

print(array24[1, :2])
print(array24[1:2, :2])

输出:

[4 5]
[[4 5]]

代码:

print(array24[::2, ::2])

输出:

[[1 3]
 [7 9]]

代码:

print(array24[::-2, ::-2])

输出:

[[9 7]
 [3 1]]

关于数组的索引和切片运算,大家可以通过下面的两张图来增强印象,这两张图来自《利用Python进行数据分析》一书,它是pandas的作者Wes McKinney撰写的Python数据分析领域的经典教科书,有兴趣的读者可以购买和阅读原书。

90365658da8546cfad8c84c83b64a52e.png

f236f3af227a9dc24175811814e62fd9.png
  • 花式索引(fancy index)- 利用整数数组进行索引,这里所说的整数数组可以是NumPy的ndarray,也可以是Python中listtuple等可迭代类型,可以使用正向或负向索引。

代码:

array25 = np.array([50, 30, 15, 20, 40])
array25[[0, 1, -1]]

输出:

array([50, 30, 40])

代码:

array26 = np.array([[30, 20, 10], [40, 60, 50], [10, 90, 80]])
# 取二维数组的第1行和第3行
array26[[0, 2]]

输出:

array([[30, 20, 10],
       [10, 90, 80]])

代码:

# 取二维数组第1行第2列,第3行第3列的两个元素
array26[[0, 2], [1, 2]]

输出:

array([20, 80])

代码:

# 取二维数组第1行第2列,第3行第2列的两个元素
array26[[0, 2], 1]

输出:

array([20, 90])
  • 布尔索引 - 通过布尔类型的数组对数组元素进行索引,布尔类型的数组可以手动构造,也可以通过关系运算来产生布尔类型的数组。

代码:

array27 = np.arange(1, 10)
array27[[True, False, True, True, False, False, False, False, True]]

输出:

array([1, 3, 4, 9])

代码:

array27 >= 5

输出:

array([False, False, False, False,  True,  True,  True,  True,  True])

代码:

array27[array27 >= 5]

输出:

array([5, 6, 7, 8, 9])
提示:切片操作虽然创建了新的数组对象,但是新数组和原数组共享了数组中的数据,简单的说,如果通过新数组对象或原数组对象修改数组中的数据,其实修改的是同一块数据。花式索引和布尔索引也会创建新的数组对象,而且新数组复制了原数组的元素,新数组和原数组并不是共享数据的关系,这一点通过前面讲的数组的 base属性也可以了解到,大家一定要注意。

案例:通过数组切片处理图像

学习基础知识总是比较枯燥且没有成就感的,所以我们还是来个案例为大家演示下上面学习的数组索引和切片操作到底有什么用。前面我们说到过,可以用三维数组来表示图像,那么通过图像对应的三维数组进行操作,就可以实现对图像的处理,如下所示。

读入图片创建三维数组对象。

guido_image = plt.imread('guido.jpg')
plt.imshow(guido_image)

对数组的0轴进行反向切片,实现图像的垂直翻转。

plt.imshow(guido_image[::-1])

f5c77e14cba8c6b59616b0261dfd7ad9.png

对数组的1轴进行反向切片,实现图像的水平翻转。

plt.imshow(guido_image[:,::-1])

5b24136d3bc8f98856340e98898eb1e7.png

将Guido的头切出来。

plt.imshow(guido_image[30:350, 90:300])

aa2fb55e513544ba13763a29fd1c7da2.png

数组对象的方法

统计方法

ndarray对象的统计方法主要包括:summeanstdvarminmaxargminargmaxcumsum等,分别用于对数组中的元素求和、求平均、求标准差、求方差、找最大、找最小、求累积和等,请参考下面的代码。

array28 = np.array([1, 2, 3, 4, 5, 5, 4, 3, 2, 1])
print(array28.sum())
print(array28.mean())
print(array28.max())
print(array28.min())
print(array28.std())
print(array28.var())
print(array28.cumsum())

输出:

30
3.0
5
1
1.4142135623730951
2.0
[ 1  3  6 10 15 20 24 27 29 30]

其他方法

  • all() / any()方法:判断数组是否所有元素都是True / 判断数组是否有为True的元素。
  • astype()方法:拷贝数组,并将数组中的元素转换为指定的类型
  • dot()方法:实现一个数组和另一个数组的点积运算。在数学上,点积(dot product)又称数量积标量积,是一种接受两个等长的数字序列,返回单个数字的代数运算。从代数角度看,先对两个数字序列中的每组对应元素求积,再对所有积求和,结果即为点积,即:
    equation?tex=%5Cboldsymbol%7BA%7D+%5Ccdot+%5Cboldsymbol%7BB%7D+%3D+%5Csum_%7Bi%3D1%7D%5E%7Bn%7Da_ib_i 。从几何角度看,点积则是两个向量的长度与它们夹角余弦的积,即:
    equation?tex=%5Cboldsymbol%7BA%7D+%5Ccdot+%5Cboldsymbol%7BB%7D%3D%7C%5Cboldsymbol%7BA%7D%7C%7C%5Cboldsymbol%7BB%7D%7C%5Ccos%7B%5Ctheta%7D 。在欧几里得几何中,两个笛卡尔坐标向量的点积也称为
    内积(inner product),NumPy中也提供了实现内积的函数,但是内积的含义要高于点积,点积相当于是内积在欧几里得空间
    equation?tex=%5Cmathbb%7BR%7D%5En 的特例,而内积可以推广到
    赋范向量空间(不理解没有关系,当我没说就行了)。

代码:

array29 = np.array([3, 4])
array30 = np.array([5, 6])
array29.dot(array30)

输出:

39

代码:

array31 = np.array([[1, 2, 3], [4, 5, 6]])
array32 = np.array([[1, 2], [3, 4], [5, 6]])
array31.dot(array32)

输出:

array([[22, 28],
       [49, 64]])
说明:可以看出,二维数组的点积就是矩阵乘法运算。
  • dump()方法:保存数组到文件中,可以通过NumPy中的load函数从保存的文件中加载数据创建数组。

代码:

array31.dump('array31-data')
array32 = np.load('array31-data', allow_pickle=True)
array32

输出:

array([[1, 2],
       [3, 4],
       [5, 6]])
  • fill()方法:向数组中填充指定的元素。
  • flatten()方法:将多维数组扁平化为一维数组。

代码:

array32.flatten()

输出:

array([1, 2, 3, 4, 5, 6])
  • nonzero()方法:返回非0元素的索引。
  • round()方法:对数组中的元素做四舍五入操作。
  • sort()方法:对数组进行就地排序。

代码:

array33 = np.array([35, 96, 12, 78, 66, 54, 40, 82])
array33.sort()
array33

输出:

array([12, 35, 40, 54, 66, 78, 82, 96])
  • swapaxes()transpose()方法:交换数组指定的轴。

代码:

# 指定需要交换的两个轴,参数顺序无所谓
array32.swapaxes(0, 1)

输出:

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

代码:

# 对于二维数组,transpose相当于实现了矩阵的转置
array32.transpose()

输出:

array([[1, 3, 5],
       [2, 4, 6]])
  • take()方法:从数组中取指定索引的元素,类似于花式索引。

代码:

array34 = array33.take([0, 2, -3, -1])
array34

输出:

array([12, 40, 78, 96])
  • tolist()方法:将数组转成Python中的list
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值