我正在尝试在Python中构造一个structured array
,可以通过列和行的名称进行访问。使用numpy的structured array
方法可以实现吗?
实施例: 我的数组应该大致有这种形式:
My_array = A B C
E 1 2 3
F 4 5 6
G 7 8 9
我希望有可能做到以下几点:
My_array["A"]["E"] = 1
My_array["C"]["F"] = 6
是否可以使用structured arrays
在pyhton中执行此操作,还是有其他类型的结构更适合此类任务?
答案 0 :(得分:1)
使用重新排列,您可以使用点表示法或具有列名称的特定参考来访问列。对于行,可通过行号访问它们。我还没有通过行名访问它们,例如:
>>> import numpy as np
>>> a = np.arange(1,10,1).reshape(3,3)
>>> dt = np.dtype([('A','int'),('B','int'),('C','int')])
>>> a.dtype = dt
>>> r = a.view(type=np.recarray)
>>> r
rec.array([[(1, 2, 3)],
[(4, 5, 6)],
[(7, 8, 9)]],
dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')])
>>> r.A
array([[1],
[4],
[7]])
>>> r['A']
array([[1],
[4],
[7]])
>>> r.A[0]
array([1])
>>> a['A'][0]
array([1])
>>> # now for the row
>>> >>> r[0]
rec.array([(1, 2, 3)],
dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')])
>>>
您可以同时指定dtype和类型
>>> a = np.ones((3,3))
>>> b = a.view(dtype= [('A','<f8'), ('B','<f8'),('C', '<f8')], type = np.recarray)
>>> b
rec.array([[(1.0, 1.0, 1.0)],
[(1.0, 1.0, 1.0)],
[(1.0, 1.0, 1.0)]],
dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
>>> b.A
array([[ 1.],
[ 1.],
[ 1.]])
>>> b.A[0]
array([ 1.])
答案 1 :(得分:1)
基本结构化数组为您提供了可以使用一个名称编制索引的内容:
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
或.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
文件,最常生成结构化数组。结果是每个标记列的命名字段,以及文件中每行的编号“行”。