3

我正在尝试structured array在 Python 中构建一个可以通过列名和行名访问的。用structured arraynumpy的方法可以吗?

示例:我的数组应该大致有这种形式:

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

是否可以在 pyhton 中使用structured arrays或者是否有另一种更适合此类任务的结构?

4

2 回答 2

2

一个基本的结构化数组为您提供了可以用一个名称索引的东西:

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从技术上讲,领域不是一个维度。它们不在数组的.shapeor中注册。.ndim你也不能使用x[0,'A'].

recarray做同样的事情,但添加了作为属性访问字段的选项,例如x.Bx['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.genfromtxtloadtxt

于 2015-07-10T16:40:05.407 回答
1

使用recarray,您可以使用点符号或对列名的特定引用来访问列。对于行,它们按行号访问。我还没有看到通过行名访问它们,例如:

>>> 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和type

>>> 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.])
于 2015-07-10T10:03:38.607 回答