2

我目前尝试将大量数组打包到 numpy 结构化数组中。根据numpy 文档

子数组始终具有 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制作子数组的逐行子数组,同时为每个子数组指定形状直接连续存储每个子-大批?
当所有子数组的第一个维度相等而第二个维度不相等时,最好的处理方法是什么?我应该直接指定每个形状以保持它们连续吗?

4

1 回答 1

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])
于 2018-08-17T15:46:59.823 回答