1. ndarray对象
NumPy 定义了一个 n 维数组对象,简称 ndarray 对象,它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块
ndarray 对象采用了数组的索引机制,将数组中的每个元素映射到内存块上,并且按照一定的布局对内存块进行排列(行或列)。
2. 创建数组
numpy.array(object, dtype = None, copy = True, order = None,subok=False,ndmin = 0)
序号 | 参数 | 描述说明 |
1 | object | 表示一个数组序列。 |
2 | dtype | 可选参数,通过它可以更改数组的数据类型 |
3 | copy | 可选参数,当数据源是ndarray时表示数组能否被复制,默认是 True。 |
4 | order | 可选参数,以哪种内存布局创建数组,有 3 个可选值,分别是 C(行序列) /F(列序列)/A(默认)。 |
5 | ndmin | 可选参数,用于指定数组的维度。 |
6 | subok | 可选参数,类型为bool值,默认False。为True,使用object的内部数据类 型;False:使用object数组的数据类型。 |
#array()函数,括号内可以是列表、元祖、数组、迭代对象,生成器等
np.array([1,2,3,4,5])
# 元组
np.array((1,2,3,4,5))
a = np.array([1,2,3,4,5])
# 数组
np.array(a)
# 迭代对象
np.array(range(10))
# 生成器
np.array([i**2 for i in range(10)])
# 列表中元素类型不相同 转化为字符型
np.array([1,1.5,3,4.5,'5']) # 选择所占内存最大的元素类型
# 有整形和浮点型 转化为浮点型
np.array([1,2,3.14,4,5]) # 浮点型
# 二维数组:嵌套序列(列表,元祖均可)
np.array([
[1,2,3],('a','b','c')
])
# 注意嵌套序列数量不一会怎么样 -> 变成一维
np.array([[1,2,3],[1,2,3,4]]) # array([list([1, 2, 3]), list([1, 2, 3, 4])], dtype=object)
# 设置数组元素类型 整形 -> 浮点
np.array([1,2,3,4,5],dtype='float')
# 浮点 -> 整形 (舍去小数点后的数字)
np.array([1.1,2.5,3.8,4,5],dtype='int')
关于copy参数
# 设置copy参数,默认为True -> 内存地址不同
a = np.array([1,2,3,4,5])
# 定义b,复制a
b = np.array(a) # 若此时采用b = a 则内存地址相同
# 输出a和b的id
print('a:', id(a), ' b:', id(b)) # a: 2066732212352 b: 2066732213152
# a =--复制
# b ---未复制
b[0] = 10
# 当修改b的元素时,a不会发生变化
print(a) # [1 2 3 4 5]
a = np.array([1,2,3,4,5])
# 定义b,当设置copy参数为Fasle时,不会创建副本,
# 两个变量会指向相同的内容地址,没有创建新的对象
b = np.array(a, copy=False)
# 输出a和b的id
print('a:', id(a), ' b:', id(b)) # a: 2066732267520 b: 2066732267520
# 由于a和b指向的是相同的内存地址,因此当修改b的元素时,a会发生变化
b[0] = 10
print('a:',a,' b:',b) # a: [10 2 3 4 5] b: [10 2 3 4 5]
ndmin指定数组纬度
a = np.array([1,2,3]) # [1,2,3]
a = np.array([1,2,3], ndmin=2) # [[1,2,3]]
subok参数
# 创建一个矩阵
a = np.mat([1,2,3,4])
# 输出为矩阵类型
print(type(a)) # <class 'numpy.matrix'>
# 既要复制一份副本,又要保持原类型
at = np.array(a,subok=True)
af = np.array(a) # 默认为False
print('at,subok为True:',type(at)) # at,subok为True: <class 'numpy.matrix'>
print('af,subok为False:',type(af)) # af,subok为False: <class 'numpy.ndarray'>
print(id(at),id(a)) # 2066738151720 2066738151608
注意:
#定义个数组
a = np.array([2,4,3,1])
# 在定义b时,如果想复制a的几种方案:
# 1.使用np.array() -> 内存地址不同
b = np.array(a)
print('b = np.array(a):',id(b),id(a))
# 2.使用数组的copy()方法 -> 内存地址不同
c = a.copy()
print('c = a.copy():',id(c),id(a))
# 注意不能直接使用=号复制,直接使用=号,会使2个变量指向相同的内存地址
d = a
# 修改d也会相应的修改a
print('d = a:',id(d),id(a))
NumPy 创建区间数组
根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。
numpy.arange(start, stop, step, dtype)
序号 | 参数 | 描述说明 |
1 | start | 起始值,默认为0 |
2 | stop | 终止值(不包含) |
3 | step | 步长,默认为1 |
4 | dtype | 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。 |
np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 可以使用浮点型数值
np.arange(3.1) # array([0., 1., 2., 3.])
# 注意 range(3.1) 会报错
x = np.arange(5, dtype = float) # array([0., 1., 2., 3., 4.])
# 起始10 ,终止值20 步长2
np.arange(10,20,2) # array([10, 12, 14, 16, 18])
# 起始0 ,终止值10 步长3
ar2 = np.arange(0,20,3) # 不能写为np.arange(20,3) 2个参数表示起始值和终止值
print(ar2) # [ 0 3 6 9 12 15 18]
ar3 = np.arange(20,step=3) # array([ 0, 3, 6, 9, 12, 15, 18])
# 如果数组太大而无法打印,NumPy会自动跳过数组的中心部分,并只打印边角:
np.arange(10000) # array([ 0, 1, 2, ..., 9997, 9998, 9999])
如何防止 float 不精确影响numpy.arange
# 想得到一个长度为3的、从0.1开始的、间隔为0.1的数组,想当然地如下coding,结果意料之外
np.arange(0.1,0.4,0.1) # array([0.1, 0.2, 0.3, 0.4])
注意:ceil((stop - start)/step)确定项目数,小浮点不精确(stop = .400000001)可以向列表中添加意外值。
NumPy 创建等差数列
函数用于创建一个一维数组,数组是一个等差数列构成的
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
序号 | 参数 | 描述说明 |
1 | start | 序列的起始值 |
2 | stop | 序列的终止值,如果endpoint为true,该值包含于数列中 |
3 | num | 要生成的等步长的样本数量,默认为50 |
4 | endpoint | 该值为 true 时,数列中包含stop值,反之不包含,默认是True。 |
6 | retstep | 如果为 True 时,生成的数组中会显示间距,反之不显示。 |
6 | dtype | ndarray 的数据类型 |
# 以下实例用到三个参数,设置起始点为 1 ,终止点为 10,数列个数为 10。
a = np.linspace(1,10,10) # array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
a = np.linspace(1,10,endpoint=False)
'''array([1. , 1.18, 1.36, 1.54, 1.72, 1.9 , 2.08, 2.26, 2.44, 2.62, 2.8 ,
2.98, 3.16, 3.34, 3.52, 3.7 , 3.88, 4.06, 4.24, 4.42, 4.6 , 4.78,
4.96, 5.14, 5.32, 5.5 , 5.68, 5.86, 6.04, 6.22, 6.4 , 6.58, 6.76,
6.94, 7.12, 7.3 , 7.48, 7.66, 7.84, 8.02, 8.2 , 8.38, 8.56, 8.74,
8.92, 9.1 , 9.28, 9.46, 9.64, 9.82])'''
# 设置起始位置为2.0,终点为3,0 数列个数为5
ar1 = np.linspace(2.0, 3.0, num=5) # array([2. , 2.25, 2.5 , 2.75, 3. ])
# 设置参数endpoint 为False时,不包含终止值
ar1 = np.linspace(2.0, 3.0, num=5, endpoint=False) # array([2. , 2.2, 2.4, 2.6, 2.8])
#设置retstep显示计算后的步长
ar1 = np.linspace(2.0,3.0,num=5, retstep=True) # (array([2. , 2.25, 2.5 , 2.75, 3. ]), 0.25)
NumPy 创建等比数列
函数用于创建一个一维数组,数组是一个等比数列构成的
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
序号 | 参数 | 描述说明 |
1 | start | 序列的起始值:序列的起始值为:base ** start |
2 | stop | 序列的终止值为:base ** stop。如果endpoint为true,该值包含于数列中 |
3 | num | 要生成的等步长的样本数量,默认为50 |
4 | endpoint | 该值为 true 时,数列中包含stop值,反之不包含,默认是True。 |
5 | base | 对数 log 的底数。 |
6 | dtype | ndarray 的数据类型 |
# 起始值为2**0 终止值为2**9 总共生成10个数
a = np.logspace(0,9,10,base=2) # array([ 1., 2., 4., 8., 16., 32., 64., 128., 256., 512.])
# 我们先使用前3个参数,将[1,5]均匀分成3个数,得到{1,3,5},
# 然后利用第4个参数base=2(默认是10)使用指数函数可以得到最终输出结果 {2^1,2^3,2^5}
np.logspace(1,5,3,base=2) # array([ 2., 8., 32.])
# 起始值为10**1 终止值为10**2 总共生成10个数
np.logspace(1.0,2.0,num=10)
a = np.linspace(1.0,2.0,num=10)
10 ** a # 等价于np.logspace(1.0, 2.0, num=10)
NumPy 创建全0或全1数列:初始化矩阵
创建指定大小的数组,数组元素以 0 来填充
numpy.zeros(shape, dtype = float, order = 'C')
序号 | 参数 | 描述说明 |
1 | shape | 数组形状 |
2 | dtype | ndarray 的数据类型 |
# 默认为浮点数
np.zeros(5)
# 设置为整形
np.zeros((5,), dtype = 'int')
# 2行2列的全0数组
np.zeros((2,2))
# zeros_like返回具有与给定数组相同的形状和类型的零数组
ar1 = np.array([[1,2,3],[4,5,6]])
np.zeros_like(ar1)
创建指定形状的数组,数组元素以 1 来填充
numpy.ones(shape, dtype = None, order = 'C')
序号 | 参数 | 描述说明 |
1 | shape | 数组形状 |
2 | dtype | ndarray 的数据类型 |
3. 数组的属性
NumPy 数组的维度称为轴。为了更直观的理解,可以将其与现实世界联系起来,比如在平面中即二维的世界中,我们描述一个点的时候,通常使用 x 轴、y 轴,这样就能确定一个点的具体位置了。因此,这里的两个维度,也就跟两个轴对应了起来。如果是立体的三维世界中,我们就会多出一个z轴,以此更加准确的来反映点的位置。所以,我么可以把以上的维度和轴进行等价。
NumPy 数组的维数称为秩(rank)?它是指轴的数量,或者维度的数量,是一个标量,一维数组的秩为 1,二维数组的秩为 2,以此类推
很多时候可以声明轴axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。
使用0值表示沿着每一列或行标签/索引值向下执行方法
使用1值表示沿着每一行或者列标签横向执行对应的方法
所以,mean(axis=0)计算的是每一列平均值, mean(axis=1)计算的是每一行平均值。
NumPy 的数组中比较重要 ndarray 对象属性有:
属性 | 说明 |
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
1.ndarray.shape
返回一个包含数组维度的元组,对于矩阵,n 行 m 列,它也可以用于调整数组维度
a = np.array([1,2,3,4,5, 6])
print('一维数组:',a.shape) # 一维数组: (6,)
b = np.array([[1, 2, 3], [4, 5, 6]])
print('二维数组:', b.shape) # 二维数组: (2, 3)
c = np.array([
[
[1, 2, 3],
[4, 5, 6]
],
[
[11, 22, 33],
[44, 55, 66]
]
])
print('三维数组:', c.shape) # 三维数组: (2, 2, 3)
调整维度 reshape
返回调整维度后的副本,而不改变原 ndarray。
a = np.array([1,2,3,4,5, 6])
# 使用a数组,创建一个新的数组b,并向形状修改为2行3列
b = a.reshape((2,3))
print('b的形状:',b.shape) # b的形状: (2, 3)
print('b:', b) # b: [[1 2 3],[4 5 6]]
print('a的形状:',a.shape) # a的形状: (6,)
print('a:', a) # a: [1 2 3 4 5 6]
调整维度 resize
numpy.resize(a, new_shape)如果新数组大于原始数组,则新数组将填充a的重复副本。
请注意,此行为与a.resize(new_shape)不同,后者用零而不是重复的a填充。
# a 为2行2列
a=np.array([
[0,1],
[2,3]
])
# b为原数组创建2行10列的新数组
b = np.resize(a,(2,10))
'''array([[0, 1, 2, 3, 0, 1, 2, 3, 0, 1],
[2, 3, 0, 1, 2, 3, 0, 1, 2, 3]])'''
a.resize((3,4), refcheck=False)
'''array([0,1,2,3],
[0,0,0,0],
[0,0,0,0])'''
2. ndarray.ndim
返回数组的维度(秩):轴的数量,或者维度的数量,是一个标量,一维数组的秩为 1,二维数组的秩为 2
a = np.array([1,2,3,4,5, 6])
b = a.reshape((2,3))
c = np.array([
[
[1, 2, 3],
[4, 5, 6]
],
[
[11, 22, 33],
[44, 55, 66]
]
])
print('a的ndim:',a.ndim) # a的ndim: 1
print('b的ndim:', b.ndim) # b的ndim: 2
print('c的ndim:', c.ndim) # c的ndim: 3
3. ndarray.size
数组元素的总个数,相当于 .shape 中 n*m 的值
a = np.array([1,2,3,4,5,6])
print('[1,2,3,4,5,6]的size:', a.size) # 6
a = np.array([[1,2,3],[4,5,6]])
print('[[1,2,3],[4,5,6]]的size:', a.size) # 6
len(a) # 2
4. ndarray.dtype
ndarray 对象的元素类型
a = np.array([1,2,3,4,5,6])
print(a.dtype) # int32
b = np.array([1.1,2,3,4,5,6])
print(b.dtype) # float64
方法astype()
numpy数据类型转换,调用astype返回数据类型修改后的数据,但是源数据的类型不会变
a=np.array([1.1, 1.2])
print('a数据类型:',a.dtype) # float64
print('astype修改数据类型:',a.astype('int').dtype) # int32
print('原数据类型未改变',a.dtype) # float64
5. ndarray.itemsize
以字节的形式返回数组中每一个元素的大小。
例如,一个元素类型为 float64 的数组 itemsize 属性值为 8(float64 占用 64 个 bits,每个字节长度为 8,所以 64/8,占用 8 个字节)
a = np.array([1.1,2.2,3.3])
print('dtype:',a.dtype,' itemsize:',a.itemsize) # dtype: float64 itemsize: 8
b = np.array([1,2,3,4,5])
print('dtype:',b.dtype,' itemsize:',b.itemsize) # dtype: int32 itemsize: 4
4. 数组的类型
numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型
名称 | 描述 | 名称 | 描述 |
---|---|---|---|
bool_ | 布尔型数据类型(True 或者 False) | float_ | float64 类型的简写 |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) | float16/32/64 | 半精度浮点数:1 个符号位,5 个指数位,10个尾数位 单精度浮点数:1 个符号位,8 个指数位,23个尾数位 双精度浮点数,包括:1 个符号位,11 个指数位,52个尾数位 |
intc | 和 C 语言的 int 类型一样,一般是 int32 或 int 64 | complex_ | 复数类型,与 complex128 类型相同 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,通常为 int32 或 int64) | complex64/128 | 复数,表示双 32 位浮点数(实数部分和虚数部分) 复数,表示双 64 位浮点数(实数部分和虚数部分) |
int8/16/32/64 | 代表与1字节相同的8位整数 代表与2字节相同的16位整数 代表与4字节相同的32位整数 代表与8字节相同的64位整数 | str_ | 表示字符串类型 |
uint8/16/32/64 | 代表1字节(8位)无符号整数 代表与2字节相同的16位整数 代表与4字节相同的32位整数 代表与8字节相同的64位整数 | string_ | 表示字节串类型,也就是bytes类型 |
# 将数组中的类型存储为浮点型
a = np.array([1,2,3,4],dtype=np.float64) # array([1., 2., 3., 4.])
# 将数组中的类型存储为布尔类型
a = np.array([0,1,2,3,4],dtype=np.bool_)
print(a) # [False True True True True]
a = np.array([0,1,2,3,4],dtype=np.float_)
print(a) # [0. 1. 2. 3. 4.]
# str_和string_区别
str1 = np.array([1,2,3,4,5,6],dtype=np.str_)
string1 = np.array([1,2,3,4,5,6],dtype=np.string_)
str2 = np.array(['我们',2,3,4,5,6],dtype=np.str_)
print(str1,str1.dtype) # ['1' '2' '3' '4' '5' '6'] <U1
print(string1,string1.dtype) # [b'1' b'2' b'3' b'4' b'5' b'6'] |S1
print(str2,str2.dtype) # ['我们' '2' '3' '4' '5' '6'] <U2
在内存里统一使用unicode, 记录到硬盘或者编辑文本的时候都转换成了utf8 UTF-8 将Unicode编码后的字符串保存到硬盘的一种压缩编码方式
int8 :-128~127 ,超过的数值是多少?
字符串类型长度的选择:
创建字符串数组时,会取最大长度
当修改内部元素时,也最多只能保存长度为5的字符串,超过的舍去
定长不灵活效率高 可变长度灵活效率低
还可以使其接受可变长度的字符,修改str为object数据类型即可
数据类型标识码
NumPy 中每种数据类型都有一个唯一标识的字符码,如下所示:
字符 | 对应类型 | 字符 | 对应类型 |
b | 代表布尔型 | c | 复数浮点型 |
i | 带符号整型 | m | 时间间隔(timedelta) |
u | 无符号整型 | M | datatime(日期时间) |
f | 浮点型 | O | Python对象 |
S,a | 字节串(S)与字符串(a) | U | Unicode |
int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替
# 首先创建结构化数据类型
dt = np.dtype([('age','U1')])
print(dt) # [('age', '<U1')]
# 将数据类型应用于 ndarray 对象
students = np.array([("我们"),(128)],dtype=dt)
print(students,students.dtype,students.ndim) # [('我',) ('1',)] [('age', '<U1')] 1
print(students['age']) # ['我' '1']
以下示例描述一位老师的姓名、年龄、工资的特征,该结构化数据其包含以下字段:
str 字段:name
int 字段:age
float 字段:salary
teacher = np.dtype([('name',np.str_,2), ('age', 'i1'), ('salary', 'f4')])
#将其应用于ndarray对象
b = np.array([('wl', 32, 8357.50),
('lh', 28, 7856.80)], dtype = teacher)
print(b) # [('wl', 32, 8357.5) ('lh', 28, 7856.8)]
b['name'] # array(['wl', 'lh'], dtype='<U2')
b['age'] # array([32, 28], dtype=int8)