[Python数据科学手册]2.9NumPy的结构化数组

275 阅读2分钟
import numpy as np 
name = ['Alice', 'Bob', 'Cathy', 'Doug']       
age = [25, 45, 37, 19]       
weight = [55.0, 85.5, 68.0, 61.5]

x = np.zeros(4,dtype=int)
#2.9使用复合数据结构的结构化数组
data = np.zeros(4,dtype={'names':('name','age','weight'),
                         'formats':('U10','i4','f8')})
# U10 表示“长度不超过 10 的 Unicode 字符串”,
# i4 表示“4 字节(即 32 比特)整型”,
# f8 表示“8 字节(即 64 比特)浮点型
print(data.dtype)
# 现在生成了一个空的数组容器,可以将列表数据放入数组中:
data['name'] = name
data['age'] = age
data['weight'] = weight
print(data)
# 所有的数据被安排在一个内存块中。
# 结构化数组的方便之处在于,你可以通过索引或名称查看相应的值:
data['name'] #获取所有名字
data[0] #获取数据第一行
data[-1]['name'] #获取数据最后一行
# 利用布尔掩码,还可以做一些更复杂的操作,如按照年龄进行筛选:
#获取年龄小于30岁的人的名字
data[data['age'] < 30]['name']
#如果希望实现比上面更复杂的操作,应考虑使用Pandas包

#2.9.1
#生成结构化数组

# 结构化数组的数据类型有多种制定方式
#字典方法:
np.dtype({'names':('name', 'age', 'weight'),                  
        'formats':('U10', 'i4', 'f8')})
# 可以用 Python 类型或 NumPy 的 dtype 类 型指定:
np.dtype({'names':('name', 'age', 'weight'),                  
'formats':((np.str_, 10), int, np.float32)})
# 复合类型也可以是元组列表:
np.dtype([('name', 'S10'), ('age', 'i4'), ('weight', 'f8')])
# 如果类型的名称对你来说并不重要,那你可以仅仅用一个字符串来指定它。
# 在该字符串中数据类型用逗号分隔:
np.dtype('S10,i4,f8')
'''
第一个(可选)字符是 < 或者 >,分别表示“低字节 序”(little endian)和“高字节序”(bid endian),
表示字节(bytes)类 型的数据在内存中存放顺序的习惯用法。
后一个字符指定的是数据的类 型:字符、字节、整型、浮点型,等等(如表 2-4 所示)。
最后一个字 符表示该对象的字节大小。
'''

#2.9.2
#更高级的数据类型

# 可以创建一种类型,其中每个元素都包含一个数组或矩阵
# 数据类型用 mat 组件包含一个 3×3 的浮点矩阵:
tp = np.dtype([('id','i8'),('mat','f8',(3,3))])
X = np.zeros(1,dtype=tp)
print(X[0])
print(X['mat'][0])
#现在 X 数组的每个元素都包含一个 id 和一个 3×3 的矩阵

#2.9.3
# 记录数组:结构化数组的扭转
# NumPy 还提供了 np.recarray 类,域可以像属性一样获取,而不是像字典的键那样获取。
data_rec = data.view(np.recarray)
data_rec.age
# 记录数组的不好的地方在于,即使使用同样的语法,在获取域时也会有 一些额外的开销
%timeit data['age']        
%timeit data_rec['age']        
%timeit data_rec.age