I think I can do: np.zeros((), dtype=dt).strides
, but this doesn't seem efficient when the dtype is a large array type like: ('<f8', (200, 100))
. Is there a way of going directly from dtype to strides in numpy?
You can actually get the strides of a sub-array within a structured array without creating the "full" array.
Sub-arrays within a structured array are required to be contiguous and in C-order according to the documentation. Note the sentence just above the first example:
Sub-arrays always have a C-contiguous memory layout.
Therefore, for a structured array with no fields such as the one in your example, you can do (as an unreadable one-liner):
import numpy as np
x = np.dtype(('<f8', (200, 100)))
strides = x.base.itemsize * np.r_[1, np.cumprod(x.shape[::-1][:-1])][::-1]
Avoiding the code golf:
shape = list(x.shape)
# First, let's make the strides for an array with an itemsize of 1 in C-order
tmp_strides = shape[::-1]
tmp_strides[1:] = list(np.cumprod(tmp_strides[:-1]))
tmp_strides[0] = 1
# Now adjust it for the real itemsize:
tmp_strides = x.base.itemsize * np.array(tmp_strides)
# And convert it to a tuple, reversing it back for proper C-order
strides = tuple(tmp_strides[::-1])
This gets more complex when there are multiple fields, however. You'd need to put in approriate checks in general. For example: Does the dtype have a shape
attribute? Does it have fields? Do any fields have shape
attributes?