一、前言

我们知道,python是一种动态语言,可以将任何类型的数据赋给任何变量,譬如:

#Python代码

x = 4x= "four"

这里已经将 x 变量的内容由整型转变成了字符串,而同样的操作在 C 语言中将会导致(取决于编译器设置)编译错误或其他未知的后果。

这种灵活性是使 Python 和其他动态类型的语言更易用的原因之一。理解这一特性如何工作是学习用 Python 有效且高效地分析数据的重要因素。但是这种类型灵活性也指出了一个事实:

Python 变量不仅是它们的值,还包括了关于值的类型的一些额外信息。

二、整型

标准的 Python 实现是用 C 语言编写的。这意味着每一个 Python 对象都是一个伪 C 语言结构体,该结构体不仅包含其值,还有其他信息。例如,当我们在 Python 中定义一个整型,例如 x = 10000 时,x 并不是一个“原生”整型,而是一个指针,指向一个 C 语言的复合结构体,结构体里包含了一些值。查看 Python 3.4 的源代码,可以发现整型(长整型)的定义,如下所示(C 语言的宏经过扩展之后):

struct_longobject {longob_refcnt;

PyTypeObject*ob_type;

size_t ob_size;long ob_digit[1];

};

Python 3.4 中的一个整型实际上包括 4 个部分。

ob_refcnt 是一个引用计数,它帮助 Python 默默地处理内存的分配和回收。

ob_type 将变量的类型编码。

ob_size 指定接下来的数据成员的大小。

ob_digit 包含我们希望 Python 变量表示的实际整型值。

这意味着与 C 语言这样的编译语言中的整型相比,在 Python 中存储一个整型会有一些开销,正如下图所示:

这里 PyObject_HEAD 是结构体中包含引用计数、类型编码和其他之前提到的内容的部分。

两者的差异在于,C 语言整型本质上是对应某个内存位置的标签,里面存储的字节会编码成整型。而 Python 的整型其实是一个指针,指向包含这个 Python 对象所有信息的某个内存位置,其中包括可以转换成整型的字节。由于 Python 的整型结构体里面还包含了大量额外的信息,所以 Python 可以自由、动态地编码。但是,Python 类型中的这些额外信息也会成为负担,在多个对象组合的结构体中尤其明显。

三、列表

设想如果使用一个包含很多 Python 对象的 Python 数据结构,会发生什么? Python 中的标准可变多元素容器是列表。可以用如下方式创建一个整型值列表:

In[1]: L = list(range(10))

L

Out[1]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In[2]: type(L[0])

Out[2]: int

或者创建一个字符串列表:

In[3]: L2 = [str(c) for c inL]

L2

Out[3]: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

In[4]: type(L2[0])

Out[4]: str

因为 Python 的动态类型特性,甚至可以创建一个异构的列表:

In[5]: L3 = [True, "2", 3.0, 4]

[type(item)for item inL3]

Out[5]: [bool, str, float, int]

但是想拥有这种灵活性也是要付出一定代价的:为了获得这些灵活的类型,列表中的每一项必须包含各自的类型信息、引用计数和其他信息;也就是说,每一项都是一个完整的 Python 对象。来看一个特殊的例子,如果列表中的所有变量都是同一类型的,那么很多信息都会显得多余——将数据存储在固定类型的数组中应该会更高效。动态类型的列表和固定类型的(NumPy 式)数组间的区别如下图所示。

在实现层面,数组基本上包含一个指向连续数据块的指针。另一方面,Python 列表包含一个指向指针块的指针,这其中的每一个指针对应一个完整的 Python 对象(如前面看到的 Python 整型)。另外,列表的优势是灵活,因为每个列表元素是一个包含数据和类型信息的完整结构体,而且列表可以用任意类型的数据填充。固定类型的 NumPy 式数组缺乏这种灵活性,但是能更有效地存储和操作数据。

四、固定类型数组

1. 使用array模块创建数组

Python 提供了几种将数据存储在有效的、固定类型的数据缓存中的选项。内置的数组(array)模块(在 Python 3.3 之后可用)可以用于创建统一类型的密集数组:

In[6]: importarray

L= list(range(10))

A= array.array('i', L)

A

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

这里的 'i' 是一个数据类型码,表示数据为整型。

更实用的是 NumPy 包中的 ndarray 对象。Python 的数组对象提供了数组型数据的有效存储,而 NumPy 为该数据加上了高效的操作。稍后将介绍这些操作,这里先展示几种创建 NumPy 数组的方法。

从用 np 别名导入 NumPy 的标准做法开始:

In[7]: import numpy as np

2. 从python列表创建NumPy 数组

首先,可以用 np.array 从 Python 列表创建数组:

In[8]: #整型数组:

np.array([1, 4, 2, 5, 3])

Out[8]: array([1, 4, 2, 5, 3])

请记住,不同于 Python 列表,NumPy 要求数组必须包含同一类型的数据。如果类型不匹配,NumPy 将会向上转换(如果可行)。这里整型被转换为浮点型:

In[9]: np.array([3.14, 4, 2, 3])

Out[9]: array([ 3.14, 4. , 2. , 3. ])

如果希望明确设置数组的数据类型,可以用 dtype 关键字:

In[10]: np.array([1, 2, 3, 4], dtype='float32')

Out[10]: array([ 1., 2., 3., 4.], dtype=float32)

最后,不同于 Python 列表,NumPy 数组可以被指定为多维的。以下是用列表的列表初始化多维数组的一种方法:

In[11]: #嵌套列表构成的多维数组

np.array([range(i, i + 3) for i in [2, 4, 6]])

Out[11]: array([[2, 3, 4],

[4, 5, 6],

[6, 7, 8]])

内层的列表被当作二维数组的行。

3. 从头创建NumPy 数组

面对大型数组的时候,用 NumPy 内置的方法从头创建数组是一种更高效的方法。以下是几个示例:

In[12]: #创建一个长度为10的数组,数组的值都是0

np.zeros(10, dtype=int)

Out[12]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

In[13]: #创建一个3×5的浮点型数组,数组的值都是1

np.ones((3, 5), dtype=float)

Out[13]: array([[ 1., 1., 1., 1., 1.],

[1., 1., 1., 1., 1.],

[1., 1., 1., 1., 1.]])

In[14]: #创建一个3×5的浮点型数组,数组的值都是3.14

np.full((3, 5), 3.14)

Out[14]: array([[ 3.14, 3.14, 3.14, 3.14, 3.14],

[3.14, 3.14, 3.14, 3.14, 3.14],

[3.14, 3.14, 3.14, 3.14, 3.14]])

In[15]: #创建一个3×5的浮点型数组,数组的值是一个线性序列

#从0开始,到20结束,步长为2

#(它和内置的range()函数类似)

np.arange(0, 20, 2)

Out[15]: array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])

In[16]: #创建一个5个元素的数组,这5个数均匀地分配到0~1

np.linspace(0, 1, 5)

Out[16]: array([ 0. , 0.25, 0.5 , 0.75, 1. ])

In[17]: #创建一个3×3的、在0~1均匀分布的随机数组成的数组

np.random.random((3, 3))

Out[17]: array([[ 0.99844933, 0.52183819, 0.22421193],

[0.08007488, 0.45429293, 0.20941444],

[0.14360941, 0.96910973, 0.946117]])

In[18]: #创建一个3×3的、均值为0、方差为1的

#正态分布的随机数数组

np.random.normal(0, 1, (3, 3))

Out[18]: array([[ 1.51772646, 0.39614948, -0.10634696],

[0.25671348, 0.00732722, 0.37783601],

[0.68446945, 0.15926039, -0.70744073]])

In[19]: #创建一个3×3的、[0, 10)区间的随机整型数组

np.random.randint(0, 10, (3, 3))

Out[19]: array([[2, 3, 4],

[5, 7, 8],

[0,5, 0]])

In[20]: #创建一个3×3的单位矩阵

np.eye(3)

Out[20]: array([[ 1., 0., 0.],

[ 0.,1., 0.],

[ 0., 0.,1.]])

In[21]: #创建一个由3个整型数组成的未初始化的数组

#数组的值是内存空间中的任意值

np.empty(3)

Out[21]: array([ 1., 1., 1.])

五、NumPy标准数据类型

NumPy 数组包含同一类型的值,因此详细了解这些数据类型及其限制是非常重要的。因为 NumPy 是在 C 语言的基础上开发的,所以 C、Fortran 和其他类似语言的用户会比较熟悉这些数据类型。

数据类型

描述

bool_

布尔值(真、True 或假、False),用一个字节存储

int_

默认整型(类似于 C 语言中的 long,通常情况下是 int64 或 int32)

intc

同 C 语言的 int 相同(通常是 int32 或 int64)

intp

用作索引的整型(和 C 语言的 ssize_t 相同,通常情况下是 int32 或 int64)

int8

字节(byte,范围从–128 到 127)

int16

整型(范围从–32768 到 32767)

int32

整型(范围从–2147483648 到 2147483647)

int64

整型(范围从–9223372036854775808 到 9223372036854775807)

uint8

无符号整型(范围从 0 到 255)

uint16

无符号整型(范围从 0 到 65535)

uint32

无符号整型(范围从 0 到 4294967295)

uint64

无符号整型(范围从 0 到 18446744073709551615)

float_

float64 的简化形式

float16

半精度浮点型:符号比特位,5 比特位指数(exponent),10 比特位尾数(mantissa)

float32

单精度浮点型:符号比特位,8 比特位指数,23 比特位尾数

float64

双精度浮点型:符号比特位,11 比特位指数,52 比特位尾数

complex_

complex128 的简化形式

complex64

复数,由两个 32 位浮点数表示

complex128

复数,由两个 64 位浮点数表示

上表列出了标准 NumPy 数据类型。请注意,当构建一个数组时,你可以用一个字符串参数来指定数据类型:

np.zeros(10, dtype='int16')

或者用相关的 NumPy 对象来指定:

np.zeros(10, dtype=np.int16)

还可以进行更高级的数据类型指定,例如指定高位字节数或低位字节数;更多的信息可以在 NumPy 文档(http://numpy.org/)中查看。

六、参考

1. 《Python数据科学手册》 [美] Jake VanderPlas [VanderPlas, Jake]

(完)

python的底层是c_python基本数据类型底层实现相关推荐

  1. Redis五种基本数据类型底层详解(原理篇)

    Redis五种基本数据类型底层详解 详细介绍Redis用到的数据结构 简单动态字符串 SDS和C字符串的区别 总结 链表 字典 哈希表 字典 哈希算法 解决键冲突 rehash(重点) 渐进式reha ...

  2. python基础数据实例_Python基本数据类型及实例详解

    Python 中的变量不需要声明.每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建. 在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对 ...

  3. python不支持以下哪种数据类型_Python 不支持以下哪种数据类型?

    Python 不支持以下哪种数据类型? 答:char 中国大学MOOC: 为了充分利用学习时间,下列方法可行的是: 答:尽量选择理想的固定场所学习\n充分利用等候和其它碎片时间\n把握一天中的最佳状态 ...

  4. python的变量和简单的数据类型

    决定学习python这门语言了,本人资质愚钝,只会把学到的东西记录下来,供自己查漏补缺,也可以分享给和我一样正在学习python语言的人,若在记录中存在什么错误,希望多多批评指正,谢谢. Python ...

  5. group by rollup 变量名为空值_【Python学习笔记】07、数据类型和变量

    在Python中,能够直接处理的数据类型有以下几种: 整数 Python可以处理任意大小的整数,包括负整数,例如:1,100,-8080,0,等等. 计算机由于使用二进制,所以,有时候用十六进制表示整 ...

  6. Interview:算法岗位面试—10.11下午—上海某公司算法岗位(偏机器学习,互联网数字行业)技术面试考点之XGBoost的特点、python的可变不可变的数据类型、赋值浅拷贝深拷贝区别

    ML岗位面试:10.11下午-上海某公司算法岗位(偏机器学习,互联网数字行业)技术面试考点之XGBoost的特点.python的可变不可变的数据类型.赋值浅拷贝深拷贝区别 Interview:算法岗位 ...

  7. ora-00923数据类型不一致_小白学 Python(2):基础数据类型(上)

    如果我的文章对您有帮助,请关注支持下作者的公众号:极客挖掘机,获取最新干货推送:) 人生苦短,我选Python 引言 前文传送门 小白学 Python(1):开篇 接触一门新的语言,肯定要先了解它的基 ...

  8. python篇第6天【数据类型】

    Python有五个标准的数据类型: Numbers(数字) String(字符串) List(列表) Tuple(元组) Dictionary(字典) Python数字 数字数据类型用于存储数值. 他 ...

  9. python语言中包含的标准数据类型_python标准数据类型(笔记一)

    关于python,它是一种解释型,面对对象,带有动态语义的高级程序设计语言. 之前学习python的时候,简单的将python的基础内容过了一遍,然后在工作中需要用到什么就相应的去加深某一模块的需求以 ...

最新文章

  1. 移除 RSA-4096 Ransomware
  2. vector利用swap()函数进行内存的释放
  3. StackExchange.Redis 官方文档(六) PipelinesMultiplexers
  4. Latex 表格 行合并,列合并,控制行间距 单元格宽度
  5. SDL_gfx-2.0.23在windows平台下的编译及例子
  6. 【图像处理】中的“滤镜算法”:灰度、黑白、反向、去色、单色、高斯模糊、怀旧、连环画
  7. 读完《Effective Java》后我淦了 50 条开发技巧
  8. 全面讲解 Handler机制原理解析 (小白必看)
  9. 免费批量化音频切割软件 AutoVoiceCut
  10. 51单片机一些软件的使用
  11. UnityAR-平面检测
  12. Creo4.0安装与VS2015环境下的开发配置
  13. Excel VBA:数据管理与维护
  14. 浏览器 User-Agent 大全
  15. python字母对应序号_python获取字母在字母表对应位置的几种方法及性能对比较
  16. 安卓四大组件之广播组件(Broadcast)
  17. 毕业设计源码基于Spring Boot的旅游管理系统的实现
  18. 我对计算机专业的看法及对未来的计划
  19. 安装Python module
  20. 2021天梯赛L1-074 两小时学完C语言 题解

热门文章

  1. java编程有一筐鸡蛋_一筐鸡蛋数学题标准答案公式-一筐鸡蛋标准答案图片详细解答版下载_东坡手机下载...
  2. 16位灰度数据成像_16位 250M双通道PCI数据采集卡 FCFR-PCI9808
  3. 发布地图服务属性表_Web3D地图来了!腾讯位置服务正式版发布!
  4. 青茶什么时候拆_为什么铁观音这么香?到底有没有添加香精?看完你就知道了...
  5. 数据库能承受多少并发量_在工业应用中,高温套管能承受多少度?
  6. Javaweb-----HTTP协议
  7. android动态更改布局宽高,动态更改Android上的线性布局宽度或高度
  8. Python中小括号( )、中括号[ ]和大括号{}分别代表什么?
  9. c++ 获取文件的hashcode_jsp 实现文件上传和下载
  10. python 怎么报错后再次启动?