numpy结构化数组中的子数组不连续

时间:2018-08-17 10:54:34

标签: python arrays numpy structured-array

我目前尝试将多个数组打包成numpy结构化数组。 根据{{​​3}}

  

子数组始终具有C连续的内存布局。

但是,如果我使用以下方法创建结构化数组:

x = np.zeros((2,), dtype=[('a', (np.float64, 5)), ('b', (np.float64, 5))])
x['a'].flags
# Out: C_CONTIGUOUS : False
#      F_CONTIGUOUS : False
#      OWNDATA : False
#      ...

x.flags
# Out: C_CONTIGUOUS : True
#      F_CONTIGUOUS : True
#      OWNDATA : True
#      ...

对数组使用(1,)的“外部”形状将产生:

x = np.zeros((1,), dtype=[('a', (np.float64, 5)),('b',(np.float64, 7))])
x['a'].flags
# Out: C_CONTIGUOUS : True
#      F_CONTIGUOUS : False
#      OWNDATA : False
#      ...

省略(1,)将产生ndim=1具有c连续性的数组。因此,仅对于结构化数组的行,报价似乎为True

让我感到困惑的是,当我直接为每个子数组指定数组形状时,就会产生连续性:

x = np.zeros((), dtype=[('a', (np.float64, (2, 5))), ('b', (np.float64, (2, 5)))])

x['a'].flags
#Out: C_CONTIGUOUS : True
#     F_CONTIGUOUS : False
#     OWNDATA : False

从numpy文档的引用中,我认为子数组总是具有C连续的内存布局,但这仅对行或给出每个数组的形状才正确。
这种行为从何而来?正在定义“外部”形状(我不知道如何称呼...),告诉numpy制作子数组的行式子数组,同时为每个子数组指定形状-array直接连续存储每个子数组?
当所有子数组的第一个维度相等而第二个维度不相等时,解决此问题的最佳方法是什么?我应该直接指定每个形状以保持它们连续吗?

1 个答案:

答案 0 :(得分:3)

您的dtype的阵列内存将为

x[0]['a'], x[0]['b']
x[1]['a'], x[1]['b']
....

也就是说,x的记录由字段'a'的5个元素组成,然后由字段'b'的5个元素组成,依此类推。

当它说subarrays are C contiguous时,是指在一个记录中只有一个字段的元素的布局。

跨记录的字段“ a”的视图将是不连续的-“ b”的元素将分隔不同记录的元素。

这同样适用于二维数组中的列切片:

In [32]: w = np.zeros((2,10))
In [33]: w.flags
Out[33]: 
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  ...
In [34]: w[:,:5].flags    # w[:,5:] elements are in between
Out[34]: 
  C_CONTIGUOUS : False
  F_CONTIGUOUS : False
  ...

当子数组为2d时(如上一个示例),此连续性注释更相关:

In [35]: dt=np.dtype([('a', (np.float64, 5)), ('b', (np.float64, (2,2)))])
In [36]: x=np.zeros((2,2,),dt,order='F')
In [37]: x.flags
Out[37]: 
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True

In [39]: x[0,0]['b'].flags
Out[39]: 
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False

虽然数组整体上是F连续的,但是'b'元素仍然是'C'连续的。


定义数组:

In [40]: x = np.array([(1,[2,3]),(4,[5,6])], dtype=[('a',int),('b',int,2)])
In [41]: x
Out[41]: array([(1, [2, 3]), (4, [5, 6])], dtype=[('a', '<i8'), ('b', '<i8', (2,))])

将数组视为简单的int dtype(并非总是可能):

In [42]: x.view(int)
Out[42]: array([1, 2, 3, 4, 5, 6])

数字将连续存储在内存中。但是“ b”字段的值不是连续的:

In [44]: x['b']
Out[44]: 
array([[2, 3],
       [5, 6]])

“ a”的值介于以下之间:

In [47]: x['a']
Out[47]: array([1, 4])