数据类型
前面说过,ndarray对象中存储的元素其类型都是相同的,而且通常是数值型的元素。与原生Python相比,NumPy提供了更多种类、更加精确的数值类型,基本上是和C语言中的数值类型是相对应的,具体可以参考 这里。说到C语言中的数值类型,我们就应该知道,在不同字长的机器上,有些相同的类型表示的数据范围是不同的,这是一个比较头疼的问题,在NumPy中,也提供了固定大小、与平台无关的数值类型。
比较常用的5种数值类型有:布尔型(bool),整型(int),无符号整型(uint),浮点型(float)和复数类型(complex)。不同类型的数值在内存中占用的空间是不一样的,有些类型,即使相同,它们不同机器上占用的内存空间也会有差别。
类型转换
这些类型可以直接作为函数将原生Python的数值类型转换为NumPy中定义的数值类型。
# 1. 直接对数值进行转换n = 1.23print(type(n)) # <class 'float'>import numpy as npn = numpy.float32(n)print(type(n)) # <class 'numpy.float32'># 2. 对 Python 序列进行转换# 数据类型发生了转换 [list --> ndarray]# 数值类型也发生了转换 [int --> int32 ]v = [1, 2, 3]np_v = np.int32(v)print(type(np_v)) # <class 'numpy.ndarray'>print(repr(np_v)) # array([1, 2, 3], dtype=int32)# 3. 直接对数组对象进行转换v = np.array([1, 2])vf = np.float32(v)print(repr(v), repr(vf)) # array([1, 2]) array([1., 2.], dtype=float32)
可以直接在构建NumPy数组的过程中用关键字参数的形式进行指明。
import numpy as npv = np.array([1, 2, 3], dtype=np.int32)print(type(v), repr(v)) # <class 'numpy.ndarray'> array([1, 2, 3], dtype=int32)
使用数组对象的astype()方法,对数组的数值类型进行转换。
import numpy as npv = np.array([1, 2, 3])fv = v.astype(np.double)print(repr(fv)) # array([1., 2., 3.]),数字后带一个小数点,作一个提示,表示浮点类型
溢出问题
在原生Python中,可能并不需要担心数据的溢出问题,因为与静态语言C不同,Python数据大小是可以动态增长的。在NumPy中,每种数值类型是固定大小的,数值过大会出现溢出的问题。
# 计算 100 的 4 次方import numpy as npresult_1 = np.power(100, 4) # 默认是和我机器字长一致result_2 = np.power(100, 4, dtype=np.int16)print(result_1, result_2) # 100000000 -7936print(type(result_1), type(result_2)) # <class 'numpy.int64'> <class 'numpy.int16'>
所以,在使用NumPy进行科学计算时,首先要对数据的量级有一个了解,便于选择合适的类型来进行数据存储。使用numpy.iinfo()和numpy.finfo()可以分别确定整数数值类型和浮点数数值类型的表示范围。
import numpy as npprint(np.iinfo(np.int32))# Machine parameters for int32# ---------------------------------------------------------------# min = -2147483648# max = 2147483647# ---------------------------------------------------------------print(np.finfo(np.float32))# Machine parameters for float32# ---------------------------------------------------------------# precision = 6 resolution = 1.0000000e-06# machep = -23 eps = 1.1920929e-07# negep = -24 epsneg = 5.9604645e-08# minexp = -126 tiny = 1.1754944e-38# maxexp = 128 max = 3.4028235e+38# nexp = 8 min = -max# ---------------------------------------------------------------
NumPy数组的创建
从原生Python类型转化
一般是通过Python的序列类型(list,tuple等)进行转化。使用函数numpy.array(),更详细的转换参数需求可以参考 这里 。
import numpy as npv = np.array([1, 2, 3])print(repr(v)) # array([1, 2, 3])v = np.array("abcd")print(repr(v)) # array('abcd', dtype='<U4')# 精度自动提升v = np.array((1, 2.3, 0))print(repr(v)) # array([1. , 2.3, 0. ])# 指定转换后的数值类型v = np.array([2, 3], dtype=np.int16)print(repr(v)) # array([2, 3], dtype=int16)# 转化成多维数组v = np.array([[1, 2], [4, 5]])print(repr(v))# array([[1, 2],# [4, 5]])# ** 每一维的数据元素个数要对其 **v = np.array([[1, 2], [3, 4, 5]])print(repr(v)) # array([list([1, 2]), list([3, 4, 5])], dtype=object)
使用内置的函数直接生成
通过一些内置的函数,可以快速生成一些特殊形式的NumPy数组。
numpy.zeros()
生成给定「尺寸」的数组,元素全为0,默认的存储类型是float。
import numpy as npv = np.zeros(2)print(repr(v)) # array([0., 0.])v = np.zeros((2, 3), dtype=np.int16)print(repr(v))# array([[0, 0, 0],# [0, 0, 0]], dtype=int16)
numpy.empty()
生成给定「尺寸」的数组,元素全未初始化,因为数值类型与C一致,所以未初始化的数据值是随机的,默认的类型是float。
import numpy as npv = np.empty((2, 2))print(repr(v))# array([[1.40735731e-311, 1.40736975e-311],# [8.61672470e-315, 8.61672486e-315]])v = np.array((2, 2), dtype=np.int16)print(repr(v))# array([[ 2678, 13056],# [ 54, 0]], dtype=int16)
numpy.ones()
生成给定「尺寸」的数组,元素全为 1 ,默认数值类型是numpy.float64
import numpy as npv = np.ones(3)print(repr(v)) # array([1., 1., 1.])v = np.ones((2, 2), dtype=int)print(repr(v))# array([[1, 1],# [1, 1]])
numpy.full()
生成给定「尺寸」,给定「元素」的数组,数组的元素都相同,存储类型由给定元素决定。
import numpy as npv = np.full(3, 666)print(repr(v)) # array([666, 666, 666])
numpy.arange()
numpy.arange([start,]stop, [step,]dtype=None)
生成给定范围和步长内的一维数组,步长可以是浮点数,数据类型根据范围和步长自动推断。
import numpy as npv = np.arange(3)print(repr(v)) # array([0, 1, 2])v = np.arange(5, 2, -1)print(repr(v)) # array([5, 4, 3])v = np.arrange(1, 2, 0.3)print(repr(v)) # array([1. , 1.3, 1.6, 1.9])
numpy.linspace()
通过给定的范围和元素个数来生成一维数组,与arange()相比,它生成的一维数组首位是可以确定的,步长通过计算来确定,而且这个函数默认是包括终止元素的。
import numpy as npv = np.linspace(1, 2, 4)print(repr(v)) # array([1. , 1.33333333, 1.66666667, 2. ])v = np.linspace(1, 2, 4, endpoint=False) # 不包括终止位置 2print(repr(v)) # array([1. , 1.25, 1.5 , 1.75])
