一个基本的结构化数组为您提供了可以用一个名称索引的东西:
In [276]: dt=np.dtype([('A',int),('B',int),('C',int)])
In [277]: x=np.arange(9).reshape(3,3).view(dtype=dt)
In [278]: x
Out[278]:
array([[(0, 1, 2)],
[(3, 4, 5)],
[(6, 7, 8)]],
dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')])
In [279]: x['B'] # index by field name
Out[279]:
array([[1],
[4],
[7]])
In [280]: x[1] # index by row (array element)
Out[280]:
array([(3, 4, 5)],
dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')])
In [281]: x['B'][1]
Out[281]: array([4])
In [282]: x.shape # could be reshaped to (3,)
Out[282]: (3, 1)
视图方法生成了一个二维数组,但只有一列。通常的列被 dtype 字段替换。它是 2d,但有一个转折。通过使用view
数据缓冲区不变;dtype 只是提供了一种访问这些“列”的不同方式。 dtype
从技术上讲,领域不是一个维度。它们不在数组的.shape
or中注册。.ndim
你也不能使用x[0,'A']
.
recarray
做同样的事情,但添加了作为属性访问字段的选项,例如x.B
与x['B']
.
rows
仍然必须通过索引号访问。
构造结构化数组的另一种方法是将值定义为元组列表。
In [283]: x1 = np.arange(9).reshape(3,3)
In [284]: x2=np.array([tuple(i) for i in x1],dtype=dt)
In [285]: x2
Out[285]:
array([(0, 1, 2), (3, 4, 5), (6, 7, 8)],
dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')])
In [286]: x2.shape
Out[286]: (3,)
ones
, zeros
,empty
也构造基本的结构化数组
In [287]: np.ones((3,),dtype=dt)
Out[287]:
array([(1, 1, 1), (1, 1, 1), (1, 1, 1)],
dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')])
我可以通过嵌套 dtypes 构造一个用 2 个字段名称索引的数组:
In [294]: dt1=np.dtype([('D',int),('E',int),('F',int)])
In [295]: dt2=np.dtype([('A',dt1),('B',dt1),('C',dt1)])
In [296]: y=np.ones((),dtype=dt2)
In [297]: y
Out[297]:
array(((1, 1, 1), (1, 1, 1), (1, 1, 1)),
dtype=[('A', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')]), ('B', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')]), ('C', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')])])
In [298]: y['A']['F']
Out[298]: array(1)
但坦率地说,这相当令人费解。我什至还没有弄清楚如何将元素设置为arange(9)
(不迭代字段名称)。
结构化数组最常通过使用(或)读取csv
文件来生成。结果是每个标记列的命名字段,以及文件中每一行的编号“行”。np.genfromtxt
loadtxt