While browsing through attributes, I found that I can change np.ndarray.strides
attribute explicitly like so:
arr = np.array([8, 3, 4], dtype=np.uint16)
arr.strides = 1
arr
>>> array([ 8, 768, 3], dtype=uint16)
I know intuitively this is not safe way to assign an attribute explicitly (might be antipattern). Despite that, I know very well, what it is supposed to do.
Another way to get my expected result is:
np.lib.stride_tricks.as_strided(arr, shape=(3,), strides=(1,))
I'm looking for any guidelines about patterns of programming that helps to understand, should I avoid setting attributes like this.
Also, is there a safer way in numpy
to assign a new value to .strides
attribute?
CodePudding user response:
np.lib.stride_tricks.sliding_window_view
is a newer, safer cover for as_strided
. However most uses of these use a strides
that is as big as the original (here 2). They return a view
, rather than modify the array itself.
Your array, and 2 ways of viewing the individual bytes:
In [529]: arr = np.array([8,3,4],'uint16')
In [530]: arr
Out[530]: array([8, 3, 4], dtype=uint16)
In [531]: arr.tobytes()
Out[531]: b'\x08\x00\x03\x00\x04\x00'
In [532]: arr.view('uint8')
Out[532]: array([8, 0, 3, 0, 4, 0], dtype=uint8)
your strides change is just a portion of
In [533]: np.lib.stride_tricks.as_strided(arr, strides=(1,), shape=(6,))
Out[533]: array([ 8, 768, 3, 1024, 4, 0], dtype=uint16)
In [535]: _.astype('uint8')
Out[535]: array([8, 0, 3, 0, 4, 0], dtype=uint8)
I think the 768
comes from the 0 3
In [537]: np.array([0,3],'uint8').view('uint16')
Out[537]: array([768], dtype=uint16)
So even though your strides
is (1,), it is still uint16
as the dtype, so displaying (8,0), (0,3), (3,0), [(0,4), (4,0)]
. Actually the safe as_strided
should have used shape=(5,)
, since the 6 actually "steps off the end".
So while changing strides
as you do is possible, I don't think it's useful. I haven't see anyone else use it. And as I show, interpreting the results requires some in depth knowledge of dtypes (and their relation to shape and strides).