I currently try to pack a multitude of arrays to numpy structured arrays. According to the numpy documentation
Sub-arrays always have a C-contiguous memory layout.
But if I create a structured array with:
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
# ...
While
x.flags
# Out: C_CONTIGUOUS : True
# F_CONTIGUOUS : True
# OWNDATA : True
# ...
And using a "outer" shape of (1,)
for the arrays yields:
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
# ...
Omitting (1,)
yields arrays with ndim=1
with c-contiguity. So the quote seems to be True only for the rows of an structured array.
What confuses me is that contiguity is given when I specify the array shape directly for each subarray:
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
From the quote of the numpy documentation I thought that sub-arrays always have a C-contiguous memory layout, but this only seems to be true for rows OR when the shape per array is given.
Where does this behavior come from? Is defining the "outer" shape (I don't know how to call it...) telling numpy to make row-wise sub-arrays of sub-arrays, while specifying the shape for each sub-array directly contiguously stores each sub-array?
What is the best way to deal with this when the first dimension of all sub-arrays is equal, while the second dimension is not? Should I specify each shape directly to keep them contiguous?