【Python进阶】你真的明白NumPy中的ndarray吗?

言有三 2021-08-09 15:41:34
Python 数组 字节数 一维数组 转置


 

如果你想掌握Python,那么NumPy是你必须要精通的。NumPy实际上是Python语言的一个扩展程序库,支持高维数组与矩阵运算,提供了大量的数学函数库。

 

1 ndarray内存机制

我们知道NumPy最重要的一个特点是其N维数组对象ndarray。通常ndarray内部由以下内容组成。

数据指针:一个指向实际数据的指针;

数据类型(dtype):描述了数组中每个元素所占的字节数;

维度(shape):一个表示数组形状(各维度大小)的元组。

跨度(strides):一个表示从当前元素前进到下一个元素需要跨过的字节数。

我们通过下面的代码看下ndarray的内容:

import numpy as np

a = np.arange(1,25).reshape((2,2,2,3))

print(type(a))

print(a.shape)

print(a.dtype)

print(a.strides)

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

这里的shape是指每个维度元素的个数这里的四维数组每个维度的元素个数分别为2、2、2和3。咦,这好像不对呀!2+2+2+3=9,这不等于24呀!难道我分析错了吗?

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

当然不是,我们首先将a输出来,结果如下:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

这里最里面一层[ ]可以代表1个一维数组,里面有3个元素。加粗的红色一对[ ]代表二维数组,它里面有二个[ ],即二维数组中有2个一维数组。所以认为第三维度中元素个数为2;加粗的紫色一对[ ]代表三维数组,它里面有二个[ ],即三维数组中有2个二维数组。所以认为第二维度中元素个数为2。同理,第一维度中元素个数为2。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

相信你现在应该明白了shape中的元组为啥是(2,2,2,3)了吧。

 

说完shape,我们再来看下dtype,它是指数组元素类型,注意,这里的数组元组就是指1,2,...,23,24这样的元素。另外数组中每个元素的类型都是相同的,在这个数组中,数组中每个元素类型都为int32。

 

最后我们再分析下跨度(strides)。它是指从当前元素前进到下一个元素需要跨过的字节数。

 

我们可以看出上面例子中的strides=(48,24,12,4)。那么这四个数是怎么来的呢?

 

我们在上面的四维数组中,dtype 为 int,而int 占 4个字节。而第四维度里面有3个元素,总字节数为12,所以从第四度跨到第三维度需要跨过的字节数为12;第三维度里面有2个元素(一维数组),每个一维数组的总字节数为12,所以从第三维度跨到第二维度需要跨过的字节数为24。同理,从第二维度跨到第一维度的字节数为48。

 

所以上面例子中的四维数组的跨度为(48,24,12,4),它在内存中的表示如下图所示:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

从上图可以明显的看出从要想到达第三维度(轴2),必须跨过第四维度(轴3),需要跨过3个元素,字节数为12;要想到达第一维度(轴0),必须跨过第二、三、四维度,总共12个元素,字节数为12*4=48。

 

这也就是在NumPy 中数据存储的方式。它存储在一个均匀连续的内存块中,可以这么理解,NumPy 将多维数组在内部以一维数组的方式存储,我们只要知道了每个元素所占的字节数(dtype)以及每个维度中元素的个数(shape),就可以快速定位到任意维度的任意一个元素。

2 NumPy高维数组索引与转置

2.1 索引

 

当提到索引时,你可能觉得很简单,不就是通过索引获取某个元素吗?道理的确是这样的。但是在面对高维数组时,通过索引来获取某个元素还是比较麻烦的。

 

下面我们通过一个案例来分析下一个四维数组的索引。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

如果我想取得上图中17这个元素,应该怎么办呢?

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

首先将这个四维数组用上图的轴的形式来表示。我们可以先把它看成四个块,其中第0轴和第1轴确定某个块的位置,第2轴和第3轴确定块中某个元素具体的位置。

 

图中的17在第3块,如下图的黄色部分,用0轴和1轴来表示的话,索引就是[1,0]。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

现在块的位置确定了,接下来我们确定块中元素的位置。如下图所示:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

17这个元素在上图中的索引为[1,1]。接下来我们只需要把确定块的索引[1,0]和确定块中元素的索引[]按照[第0轴,第1轴,第2轴,第3轴]这样的格式合并即可,在这个案例中,合并后17的索引为[1,0,1,1]。

 

当然,你可以用下面的代码确认下,我们的分析是否正确。

import numpy as np   

a = np.arange(1,25).reshape((2,2,2,3))

print(a[1,0,1,1])  

这个就是高维数组的索引,你已经明白了吗?

 

2.2 高维数组转置

 

高维数组的转置一直是学习NumPy的一个难点,尽管在NumPy中只需要调用numpy.transpose就可以完成转置操作,但是你真的能分析清楚为什么结果是这样的吗?尤其是高维数组。下面我们就举一个比较简单的例子来分析下。如下:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

上图是原数组,我们经过下面的代码进行转置,会得到如下的结果:

import numpy as np
a = np.arange(16).reshape((2,2,4))

b = a.transpose((1,0,2))
print(b)

转置后的结果:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

相信你已经看出了具体的差别了,那就是轴的索引顺序的互换。因为在代码中我们要求0轴和1轴互换,因此转置后的结果实际上就是a[1,0]会变成原数组a[0,1];a[0,1]会变成原数组a[1,0]。如果用图表示,就如下图所示:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

相信你已经明白了其中的原理了,接下来留一个思考题,如下:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

请问,从左到右怎么转置才能得到!

总结

 

本期我们介绍了ndarray的内存机制及高维数组的索引和转置。NumPy的知识还有很多,上面介绍的只是NumPy中比较难理解的几个问题,若想更加系统的学习NumPy及知道上面思考题的分析过程和答案,请移步我们的知识星球!

 

下期预告:Python库Scipy的高级应用

 

有三AI编程与开源框架知识星球

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

有三AI编程与开源框架知识星球创建了,欢迎加入,希望大家能借助这个平台,扎实自己的编程基础。

 

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

 

版权声明
本文为[言有三]所创,转载请带上原文链接,感谢
https://blog.51cto.com/u_14122493/3322263

  1. 利用Python爬虫获取招聘网站职位信息
  2. Using Python crawler to obtain job information of recruitment website
  3. Several highly rated Python libraries arrow, jsonpath, psutil and tenacity are recommended
  4. Python装饰器
  5. Python实现LDAP认证
  6. Python decorator
  7. Implementing LDAP authentication with Python
  8. Vscode configures Python development environment!
  9. In Python, how dare you say you can't log module? ️
  10. 我收藏的有关Python的电子书和资料
  11. python 中 lambda的一些tips
  12. python中字典的一些tips
  13. python 用生成器生成斐波那契数列
  14. python脚本转pyc踩了个坑。。。
  15. My collection of e-books and materials about Python
  16. Some tips of lambda in Python
  17. Some tips of dictionary in Python
  18. Using Python generator to generate Fibonacci sequence
  19. The conversion of Python script to PyC stepped on a pit...
  20. Python游戏开发,pygame模块,Python实现扫雷小游戏
  21. Python game development, pyGame module, python implementation of minesweeping games
  22. Python实用工具,email模块,Python实现邮件远程控制自己电脑
  23. Python utility, email module, python realizes mail remote control of its own computer
  24. 毫无头绪的自学Python,你可能连门槛都摸不到!【最佳学习路线】
  25. Python读取二进制文件代码方法解析
  26. Python字典的实现原理
  27. Without a clue, you may not even touch the threshold【 Best learning route]
  28. Parsing method of Python reading binary file code
  29. Implementation principle of Python dictionary
  30. You must know the function of pandas to parse JSON data - JSON_ normalize()
  31. Python实用案例,私人定制,Python自动化生成爱豆专属2021日历
  32. Python practical case, private customization, python automatic generation of Adu exclusive 2021 calendar
  33. 《Python实例》震惊了,用Python这么简单实现了聊天系统的脏话,广告检测
  34. "Python instance" was shocked and realized the dirty words and advertisement detection of the chat system in Python
  35. Convolutional neural network processing sequence for Python deep learning
  36. Python data structure and algorithm (1) -- enum type enum
  37. 超全大厂算法岗百问百答(推荐系统/机器学习/深度学习/C++/Spark/python)
  38. 【Python进阶】你真的明白NumPy中的ndarray吗?
  39. All questions and answers for algorithm posts of super large factories (recommended system / machine learning / deep learning / C + + / spark / Python)
  40. [advanced Python] do you really understand ndarray in numpy?
  41. 【Python进阶】Python进阶专栏栏主自述:不忘初心,砥砺前行
  42. [advanced Python] Python advanced column main readme: never forget the original intention and forge ahead
  43. python垃圾回收和缓存管理
  44. java调用Python程序
  45. java调用Python程序
  46. Python常用函数有哪些?Python基础入门课程
  47. Python garbage collection and cache management
  48. Java calling Python program
  49. Java calling Python program
  50. What functions are commonly used in Python? Introduction to Python Basics
  51. Python basic knowledge
  52. Anaconda5.2 安装 Python 库(MySQLdb)的方法
  53. Python实现对脑电数据情绪分析
  54. Anaconda 5.2 method of installing Python Library (mysqldb)
  55. Python implements emotion analysis of EEG data
  56. Master some advanced usage of Python in 30 seconds, which makes others envy it
  57. python爬取百度图片并对图片做一系列处理
  58. Python crawls Baidu pictures and does a series of processing on them
  59. python链接mysql数据库
  60. Python link MySQL database