Python numpy阵列中步幅的非模糊性检测
对于numpy数组Python numpy阵列中步幅的非模糊性检测,python,numpy,Python,Numpy,对于numpy数组X,其元素X[k[0],…,k[d-1]的位置与X[0,…,0]的位置偏移k[0]*s[0]+…+k[d-1]*s[d-1],其中(s[0],…,s[d-1])是表示X.strips的元组 据我所知,numpy数组规范中没有任何内容要求数组X的不同索引对应于内存中的不同地址,最简单的例子是步长的零值,例如,请参阅scipy讲座的一节 numpy是否有一个内置谓词来测试步幅和形状是否会使不同的索引映射到不同的内存地址 如果没有,如何写一个,最好是为了避免对步幅进行排序?编辑:我花
X
,其元素X[k[0],…,k[d-1]
的位置与X[0,…,0]
的位置偏移k[0]*s[0]+…+k[d-1]*s[d-1]
,其中(s[0],…,s[d-1])
是表示X.strips
的元组
据我所知,numpy数组规范中没有任何内容要求数组X
的不同索引对应于内存中的不同地址,最简单的例子是步长的零值,例如,请参阅scipy讲座的一节
numpy是否有一个内置谓词来测试步幅和形状是否会使不同的索引映射到不同的内存地址
如果没有,如何写一个,最好是为了避免对步幅进行排序?编辑:我花了一点时间才弄明白你在问什么。通过跨步技巧,可以以不同的方式索引数据缓冲区中的相同元素,而广播实际上是在封面下进行的。通常我们不担心它,因为它要么是隐藏的,要么是故意的 在快速映射中重新创建并寻找重复项可能是测试这一点的唯一方法。我不知道任何现有的功能,检查它 ================== 我不太清楚你关心什么。但让我来说明形状和步幅是如何工作的 定义3x4阵列:
In [453]: X=np.arange(12).reshape(3,4)
In [454]: X.shape
Out[454]: (3, 4)
In [455]: X.strides
Out[455]: (16, 4)
索引项目
In [456]: X[1,2]
Out[456]: 6
我可以通过ravel\u multi\u index
,在阵列的展平版本(例如原始arange
)中获取它的索引:
In [457]: np.ravel_multi_index((1,2),X.shape)
Out[457]: 6
我也可以使用步幅获得这个位置-请记住步幅是以字节为单位的(这里每个项目4个字节)
所有这些数字都与数据缓冲区的开始位置有关。我们可以从X.data
或X.\uu数组\u接口\uuu['data']
获取数据缓冲区地址,但通常不需要这样做
这一步告诉我们从一个条目到下一个,步骤4字节,从一行到下一个步骤16<代码>6位于缓冲区的下一行、上两行或24个字节处
在链接的as_-striped
示例中,stripes=(1*2,0)
生成特定值的重复索引
使用myX
:
In [460]: y=np.lib.stride_tricks.as_strided(X,strides=(16,0), shape=(3,4))
In [461]: y
Out[461]:
array([[0, 0, 0, 0],
[4, 4, 4, 4],
[8, 8, 8, 8]])
y
是一个3x4,重复索引X
的第一列
在y
中更改一个项目会导致在X
中更改一个值,但在y
中更改整行值:
In [462]: y[1,2]=10
In [463]: y
Out[463]:
array([[ 0, 0, 0, 0],
[10, 10, 10, 10],
[ 8, 8, 8, 8]])
In [464]: X
Out[464]:
array([[ 0, 1, 2, 3],
[10, 5, 6, 7],
[ 8, 9, 10, 11]])
如果你不小心的话,会产生一些奇怪的效果
好的,也许我已经明白了什么困扰着你了-我能确定这样一种情况吗?两个不同的索引元组最终指向数据缓冲区中的同一个位置?我不知道。y
步幅包含0是一个很好的指标
as__crossed
通常用于创建重叠窗口:
In [465]: y=np.lib.stride_tricks.as_strided(X,strides=(8,4), shape=(3,4))
In [466]: y
Out[466]:
array([[ 0, 1, 2, 3],
[ 2, 3, 10, 5],
[10, 5, 6, 7]])
In [467]: y[1,2]=20
In [469]: y
Out[469]:
array([[ 0, 1, 2, 3],
[ 2, 3, 20, 5],
[20, 5, 6, 7]])
再次更改y
中的1项,最终更改y中的2个值,但在X
中仅更改1个值
普通数组创建和索引没有此重复索引问题。广播可能会做一些事情,比如在封面下,将(4,)数组更改为(1,4),然后再更改为(3,4),从而有效地复制行。我认为还有另一个stride\u技巧
函数明确地实现了这一点
In [475]: x,y=np.lib.stride_tricks.broadcast_arrays(X,np.array([.1,.2,.3,.4]))
In [476]: x
Out[476]:
array([[ 0, 1, 2, 3],
[20, 5, 6, 7],
[ 8, 9, 10, 11]])
In [477]: y
Out[477]:
array([[ 0.1, 0.2, 0.3, 0.4],
[ 0.1, 0.2, 0.3, 0.4],
[ 0.1, 0.2, 0.3, 0.4]])
In [478]: y.strides
Out[478]: (0, 8)
在任何情况下,在正常的数组使用中,我们不必担心这种模糊性。我们只有通过故意的行为才能得到它,而不是偶然的行为
==============
这个测试怎么样:
def dupstrides(x):
uniq={sum(s*j for s,j in zip(x.strides,i)) for i in np.ndindex(x.shape)}
print(uniq)
print(len(uniq))
print(x.size)
return len(uniq)<x.size
In [508]: dupstrides(X)
{0, 32, 4, 36, 8, 40, 12, 44, 16, 20, 24, 28}
12
12
Out[508]: False
In [509]: dupstrides(y)
{0, 4, 8, 12, 16, 20, 24, 28}
8
12
Out[509]: True
def dupstrips(x):
uniq={sum(s*j表示s,j表示zip(x.strips,i))表示np.ndindex(x.shape)中的i}
打印(uniq)
打印(len(uniq))
印刷品(x码)
return len(uniq)这个测试已经在numpy中实现了,请参阅
该测试公开为numpy.core.multiarray\u tests.internal\u overlap(x)
例如:
>>> import numpy as np
>>> from numpy.core.multiarray_tests import internal_overlap
>>> from numpy.lib.stride_tricks import as_strided
现在,创建一个连续数组,并使用作为_-stripped
创建一个内部重叠的数组,并通过测试确认这一点:
>>> x = np.arange(3*4, dtype=np.float64).reshape((3,4))
>>> y = as_strided(x, shape=(5,4), strides=(16, 8))
>>> y
array([[ 0., 1., 2., 3.],
[ 2., 3., 4., 5.],
[ 4., 5., 6., 7.],
[ 6., 7., 8., 9.],
[ 8., 9., 10., 11.]])
>>> internal_overlap(x)
False
>>> internal_overlap(y)
True
该函数经过优化,可以快速返回Fortran或C连续数组的False
那是一个有趣的链接。我以前从未见过,尽管我似乎以某种方式偶然发现了其中的大多数想法。我刚才用as_大踏步的
在另一个SO问题中取了一个对角线。谢谢你的解释和答案。问这个问题的动机来自于试图弄清楚什么时候在一个数组上执行操作是安全的?
>>> x = np.arange(3*4, dtype=np.float64).reshape((3,4))
>>> y = as_strided(x, shape=(5,4), strides=(16, 8))
>>> y
array([[ 0., 1., 2., 3.],
[ 2., 3., 4., 5.],
[ 4., 5., 6., 7.],
[ 6., 7., 8., 9.],
[ 8., 9., 10., 11.]])
>>> internal_overlap(x)
False
>>> internal_overlap(y)
True