像这样使用 numpy.ndarray.strides 属性是一种好方法吗?
Is it a good way to use numpy.ndarray.strides attribute like this?
浏览属性时,我发现我可以像这样显式更改 np.ndarray.strides
属性:
arr = np.array([8, 3, 4], dtype=np.uint16)
arr.strides = 1
arr
>>> array([ 8, 768, 3], dtype=uint16)
我凭直觉知道这不是显式分配属性的安全方法(可能是反模式)。尽管如此,我很清楚,它应该做什么。
获得我预期结果的另一种方法是:
np.lib.stride_tricks.as_strided(arr, shape=(3,), strides=(1,))
我正在寻找任何有助于理解的编程模式指南,我是否应该避免设置这样的属性。
此外,在 numpy
中是否有更安全的方法为 .strides
属性分配新值?
np.lib.stride_tricks.sliding_window_view
是 as_strided
的更新、更安全的封面。然而,这些的大多数用途使用与原始(此处为 2)一样大的 strides
。他们return一个view
,而不是修改数组本身。
您的数组,以及查看单个字节的 2 种方式:
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)
你的步伐变化只是
的一部分
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)
我认为 768
来自 0 3
In [537]: np.array([0,3],'uint8').view('uint16')
Out[537]: array([768], dtype=uint16)
所以即使你的 strides
是 (1,),它仍然是 uint16
作为 dtype,所以显示 (8,0), (0,3), (3,0), [(0,4), (4,0)]
。实际上保险柜 as_strided
应该使用 shape=(5,)
,因为 6 实际上“离开了终点”。
因此,尽管像您那样更改 strides
是可能的,但我认为它没有用。我还没有看到其他人使用它。正如我所展示的,解释结果需要对数据类型(及其与形状和步幅的关系)有一些深入的了解。
浏览属性时,我发现我可以像这样显式更改 np.ndarray.strides
属性:
arr = np.array([8, 3, 4], dtype=np.uint16)
arr.strides = 1
arr
>>> array([ 8, 768, 3], dtype=uint16)
我凭直觉知道这不是显式分配属性的安全方法(可能是反模式)。尽管如此,我很清楚,它应该做什么。
获得我预期结果的另一种方法是:
np.lib.stride_tricks.as_strided(arr, shape=(3,), strides=(1,))
我正在寻找任何有助于理解的编程模式指南,我是否应该避免设置这样的属性。
此外,在 numpy
中是否有更安全的方法为 .strides
属性分配新值?
np.lib.stride_tricks.sliding_window_view
是 as_strided
的更新、更安全的封面。然而,这些的大多数用途使用与原始(此处为 2)一样大的 strides
。他们return一个view
,而不是修改数组本身。
您的数组,以及查看单个字节的 2 种方式:
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)
你的步伐变化只是
的一部分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)
我认为 768
来自 0 3
In [537]: np.array([0,3],'uint8').view('uint16')
Out[537]: array([768], dtype=uint16)
所以即使你的 strides
是 (1,),它仍然是 uint16
作为 dtype,所以显示 (8,0), (0,3), (3,0), [(0,4), (4,0)]
。实际上保险柜 as_strided
应该使用 shape=(5,)
,因为 6 实际上“离开了终点”。
因此,尽管像您那样更改 strides
是可能的,但我认为它没有用。我还没有看到其他人使用它。正如我所展示的,解释结果需要对数据类型(及其与形状和步幅的关系)有一些深入的了解。