结构数组
一、创建结构数组
(1)、通过字典创建
键names对应字段列表
键formats对应字段类型列表
当参数align=True时,
persontype = np.dtype({
'names' : ['name, 'age', 'weight'],
'formats' : ['S32', 'i', 'f'] }, align = True)
(2)通过元组列表创建
>>> np.dtype([('name', 'S32'), ('age', 'i4'), ('weight', 'f4')])
dtype([('name', 'S32'), ('age', '<i4'), ('weight', '<f4')])
(3)、通过字典创建
键名为字段名,键名对应的值为元组,第一个元素为键值的类型,第二个为内存地址偏移量
>>> np.dtype({'surname':('S25', 0), 'age':(np.int8, 25)})
二、创建结构体变量
#定义结构体
persontype = np.dtype({
'names' : ['name, 'age', 'weight'],
'formats' : ['S32', 'i', 'f'] }, align = True)
#创建结构体变量(通过指定dtype = persontype)
a = np.array([('Zhang', 32, 75.5), ('Wang', 24, 65.2)], dtype = persontype)
另一种描述结构体类型的方法(多个元组列表):
>>>a.dtype
dtype([('name', '|S32'), ('age', '<i4'), ('weight', '<f4')])
类型字符前面的'|', '<', '>'等字符表示字段值的字节顺序:
| : 忽视字节顺序
< : 低位字节在前, 即小端模式
> : 高位字节在前,即大端模式
三、结构数组的存取
(1)、通过索引获取结构元素
>>>a[0]
('Zhang', 32, 75.5)
这里的结果看上去是一个元组,实际上它是一个结构
(2)通过结构元素获取字段值
>>>a[0]['name']
'Zhang'
(3) 通过字段名获取结构数组的字段
>>>b = a['age']
>>>b
array([32, 24])
(4)将结构数组转换为字符串或者写到文件中
>>>a.tostring()
>>>a.tofile()
四、内存对齐
在C语言中,为了寻址方便,C语言的结构体会自动添加一些填充用的字节,这叫做内存对齐。
设置参数align = True,可以使结构数组的内存和C语言结构体一致
五、结构类型包含其他结构类型
(1)字段值为结构
>>>np.dtype(['f1', ['f2', np.int16]])
这个语句创建了一个字段名为f1的结构,f1的值是另一个结构,它含有字段名f2,其类型是16bit的整数
(2)字段值为数组
当字段值为数组时,用元组的第三个参数表示其形状
>>>np.dtype([('f0', 'i4'), ('f1', 'f8', (2,3))])
>>> a = np.dtype([('f0', 'i4'), ('f1', 'f8', (2,3))])
>>> b= np.array([(1, np.array([[1,2,3],[4,5,6]]))], dtype= a)
>>>b
array([(1, [[1., 2., 3.], [4., 5., 6.]])],
dtype=[('f0', '<i4'), ('f1', '<f8', (2, 3))])
六、内存结构
数组对象在内存中的存储:
数组的描述信息保存在一个数据结构中,这个结构引用两个对象:
用于保存数据的存储区域和用于描述元素类型的dtype对象。
-----------------------------------------
| dtype | *----------->float32
------------------------------------------
| dim count | 2
-------------------------------------------
| dimensions | 3 | 3
-------------------------------------------
|stride | 12 | 4
-------------------------------------------
| data | *---------->数据存储区域
-------------------------------------------
数组对象用strides属性保存每个轴上相邻元素的地址差,
上面的stride属性值为(12,4),则当某个轴的下标增加1时,
数据存储区域指针所增加的字节数。即是a[1, 0]比a[0, 0]的
地址大12个字节。a[1,1]比a[1, 0]大4个字节。
numpy中ufunc运算
加减乘除这些算数术运算在numpy中有专门的运算符与之对应。
但是逻辑运算就要用logical_and, logical_or, logical_not, logical_xor
(1)、np.logical_and(x1, x2, *args, **kwargs)
(2)、np.logical_or(x1, x2, *args, **kwargs)
(3)、logical_not(x, *args, **kwargs)
(4)、logical_xor()
python(numpy)中any和all方法和R的差不多
numpy中位运算符:
bitwise_and, bitwise_not, bitwise_or, bitwise_xor
python中自带的位运算符^, &, |, ~等
自定义ufunc函数: frompyfunc和vectorize函数
(1)frompyfunc:
frompyfuunc(func, nin, nout)
func是计算单个元素的函数
nin是func输入参数的个数
nout是func返回值的个数
(2)vectorize函数
vectorize(func, otype = [np.float])
广播:
numpy提供了快速产生能进行广播运算的数组的ogrid对象
>>>x,y = np.ogrid[:5, :5]
ogrid对象使用切片对象作为下标,返回用来进行广播计算的数组。切片有如下
两种形式:
开始值:结束值:步长
开始值:结束值:长度j
mgrid函数和ogrid函数类似,但是返回的是广播之后的数组