如何做numpy结构数组



我在numpy中很难理解结构数组。

假设我有

  • 两个元组列表(使用本地python类型)。foo_listbar_list .
  • len(foo_list)==len(bar_list)列表长度相同
  • 对于所有i,j: len(foo_list[i])==len(foo_list[j])len(bar_list[i])==len(bar_list[j]),每个列表中的元组都是相同的长度。但是这些长度直到运行时才知道(所以我不能硬编码成dtype字符串)
  • for all i,j: len(foo_list[i])!=len(bar_list[j])不同list中的元组有不同的长度

我如何压缩这两个一起成结构数组?
在我自己检查结构之后,指定dtype似乎会涉及到大量的字符串操作。我确实试过一次,它不是很好的代码,所以我想一定有一个更好的方法来做到这一点。

目前我正在做:目前我的解决方案是将它们压缩并传递给numpy.asarray

,但这会产生奇怪的结果。它创建了一个对象的二维数组这些对象就是数组。如果你把它切片,你会得到一个数组的数组——而不是一个二维数组。

示例数据:

foo_list = [(0.0, 1.0, 1.0, 0.0, 1.0),
 (1.0, 0.0, 1.0, 0.0, 1.0),
 (1.0, 1.0, 1.0, 0.0, 0.0),
 (0.0, 0.0, 0.0, 0.0, 1.0),
 (0.0, 1.0, 1.0, 1.0, 0.0),
 (1.0, 1.0, 1.0, 0.0, 1.0),
 (0.0, 0.0, 0.0, 0.0, 0.0),
 (0.0, 0.0, 0.0, 1.0, 0.0),
 (1.0, 1.0, 1.0, 1.0, 0.0),
 (1.0, 0.0, 0.0, 1.0, 0.0)]
bar_list = [(0.56885990540494535, 0.54212235514533669),
 (-1.0024727291757354, 0.75636919036826),
 (1.0912423038752346, 0.66209493674389353),
 (0.52256034116805239, 0.36499434352207855),
 (-1.6837689312941191, 0.90001803836488747),
 (-3.1590090289110528, -0.3383410738003263),
 (1.4080085734609102, -1.6283826051481185),
 (1.5037872498731264, 1.5673560444854553),
 (-2.271232989935922, 0.24542353558497185),
 (-1.9752557923680221, 0.07968567723276497)]

您可以创建一个结构化数组,其中每个结构都有两个字段,"foo"one_answers"bar"。每个字段是一个一维数组。下面是创建这样一个结构化数组的一种方法。

首先获取"foo"one_answers"bar"字段的长度:

In [26]: nfoo = len(foo_list[0])
In [27]: nbar = len(bar_list[0])

为结构化数组创建dtype。它有两个字段,"foo"one_answers"bar"。每个字段将包含一个浮点值数组,长度分别为nfoonbar

In [28]: dt = np.dtype([('foo', np.float64, nfoo), ('bar', np.float64, nbar)])

np.array创建数组,给它压缩列表和新的dtype。

In [29]: a = np.array(zip(foo_list, bar_list), dtype=dt)

a是一个长度为10的一维数组:

In [30]: a.shape
Out[30]: (10,)
In [31]: a
Out[31]: 
array([([0.0, 1.0, 1.0, 0.0, 1.0], [0.5688599054049454, 0.5421223551453367]),
       ([1.0, 0.0, 1.0, 0.0, 1.0], [-1.0024727291757354, 0.75636919036826]),
       ([1.0, 1.0, 1.0, 0.0, 0.0], [1.0912423038752346, 0.6620949367438935]),
       ([0.0, 0.0, 0.0, 0.0, 1.0], [0.5225603411680524, 0.36499434352207855]),
       ([0.0, 1.0, 1.0, 1.0, 0.0], [-1.683768931294119, 0.9000180383648875]),
       ([1.0, 1.0, 1.0, 0.0, 1.0], [-3.159009028911053, -0.3383410738003263]),
       ([0.0, 0.0, 0.0, 0.0, 0.0], [1.4080085734609102, -1.6283826051481185]),
       ([0.0, 0.0, 0.0, 1.0, 0.0], [1.5037872498731264, 1.5673560444854553]),
       ([1.0, 1.0, 1.0, 1.0, 0.0], [-2.271232989935922, 0.24542353558497185]),
       ([1.0, 0.0, 0.0, 1.0, 0.0], [-1.975255792368022, 0.07968567723276497])], 
      dtype=[('foo', '<f8', (5,)), ('bar', '<f8', (2,))])

我们可以用很多方法来分割a

a['foo']是来自foo_list的整个二维数组:

In [32]: a['foo']
Out[32]: 
array([[ 0.,  1.,  1.,  0.,  1.],
       [ 1.,  0.,  1.,  0.,  1.],
       [ 1.,  1.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.],
       [ 0.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  0.,  1.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  0.],
       [ 1.,  0.,  0.,  1.,  0.]])

a['bar'][0, -1]bar_list第一行的最后一列:

In [33]: a['bar'][0,-1]
Out[33]: 0.54212235514533669

a[0]['bar']bar_list的第一行。(这也可以作为a['bar'][0]访问)。

In [34]: a[0]['bar']
Out[34]: array([ 0.56885991,  0.54212236])

因为"foo"one_answers"bar"字段中的单个数据元素都是np.float64类型的,所以您可以创建该数据的二维视图。下面,v是形状为(10,7)的二维数组。

In [42]: v = a.view(np.float64).reshape(len(a), -1)
In [43]: v.shape
Out[43]: (10, 7)
In [44]: v[0]
Out[44]: 
array([ 0.        ,  1.        ,  1.        ,  0.        ,  1.        ,
        0.56885991,  0.54212236])
In [45]: v[0, -1]
Out[45]: 0.54212235514533669

但是如果你想要一个二维数组,你不需要创建一个结构化数组数组中。您可以通过几种方式直接创建二维数组。例如,

In [46]: b = np.array([f+b for f, b in zip(foo_list, bar_list)])
In [47]: b.shape
Out[47]: (10, 7)
In [48]: b[0]
Out[48]: 
array([ 0.        ,  1.        ,  1.        ,  0.        ,  1.        ,
        0.56885991,  0.54212236])
In [49]: b[0, -1]
Out[49]: 0.54212235514533669

相关内容

  • 没有找到相关文章

最新更新