【问题标题】:Sub-arrays in numpy structured array not c contiguousnumpy结构化数组中的子数组不是c连续的
【发布时间】:2018-08-17 10:54:34
【问题描述】:

我目前尝试将大量数组打包成 numpy 结构化数组。 根据to the numpy documentation

子数组始终具有 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 文档的引用中,我认为子数组 always 具有 C 连续内存布局,但这似乎仅适用于行或给定每个数组的形状时。
这种行为从何而来?正在定义“外部”形状(我不知道如何称呼它......)告诉 numpy 制作子数组的逐行子数组,同时为每个子指定形状-array 直接连续存储每个子数组?
当所有子数组的第一个维度相等而第二个维度不相等时,最好的处理方法是什么?我应该直接指定每个形状以保持它们连续吗?

【问题讨论】:

  • 你为什么担心这种连续性?
  • 我没有听懂你的最后一句话。在 dtype 定义中,必须指定子数组维度。

标签: python arrays numpy structured-array


【解决方案1】:

使用您的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])

【讨论】:

  • 非常感谢您的帮助!我将能够在星期一发布我的完整回复。 :)
  • 好的,现在我可以回复了。再次感谢!从您的帖子中得出结论,记录数组或结构化数组的所有字段和记录总共保存在连续内存中,但字段本身的连续性可以通过交错其他字段来破坏。并且记录数组的总分配内存将始终位于相同的固定内存地址。这也解释了为什么我不能从结构化数组字段到另一个数组的视图,如x['a'] = some_array_of_same_shape。这本来是我的下一个问题,但我想您的回答也解决了它。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-15
相关资源
最近更新 更多