我目前尝试将大量数组打包为 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/