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

标签 python arrays numpy structured-array

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

Sub-arrays always have a C-contiguous memory layout.

但是如果我创建一个结构化数组:

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,) 会生成具有 c 连续性的 ndim=1 数组。因此,这句话似乎仅适用于结构化数组的行

令我困惑的是,当我直接为每个子数组指定数组形状时,就会给出连续性:

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直接连续存储每个子数组?
当所有子数组的第一维相等而第二维不相等时,处理此问题的最佳方法是什么?我应该直接指定每个形状以保持它们连续吗?

最佳答案

根据您的dtype,数组内存将为

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

也就是说,x 的记录由字段“a”的 5 个元素组成,后跟字段“b”的 5 个元素,依此类推下一条记录。

当它说子数组是C连续的时,它指的是一条记录的一个字段中的元素的布局。

跨记录的字段“a”的 View 不会是连续的 - “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
  ...

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

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])

关于python - numpy 结构化数组中的子数组不连续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51893841/

相关文章:

Python numpy memmap 矩阵乘法

python - 比较多个 numpy 数组

python - 逗号分隔字符串列的二进制编码

python - 直接从 typing.NamedTuple 继承时出现奇怪的 MRO 结果

javascript for 循环数组

PHP Insert 语句插入数组值两次

python - 在numpy中显示超过16位数字

python - 如何修复 IndexError : invalid index to scalar variable

python - 如何在 Python/Numpy 中以最快的方式获取 "n"矩阵的最大值?

javascript - 如何将平面对象数组(可能有多个父对象)转换为嵌套对象数组