在Python2.4上,单冒号切片运算符:
在Numeric
矩阵上按预期工作,因为它返回所用维度的所有值。例如,2-D矩阵的所有X
和/或Y
值。
在Python2.6上,单冒号切片运算符在某些情况下似乎有不同的效果:例如,在常规的2-D MxN矩阵上,m[:]
可能导致返回zeros(<some shape tuple>, 'l')
作为结果切片。完整矩阵是人们所期望的 - 这是人们使用Python2.4获得的。
在Python2.6中使用双冒号::
或3点...
而不是单个冒号,似乎可以解决此问题并返回正确的矩阵切片。
经过一番猜测,我发现在输入0
作为停止索引时,你可以得到相同的零输出。例如m[<any index>:0]
返回相同的&#34;零&#34;输出为m[:]
。尝试执行m[:]
时,有没有办法调试正在挑选的索引?或者在两个Python版本(2.4到2.6)之间做了哪些改变会影响切片运算符的行为?
两个版本的Python之间使用的Numeric
版本(24.2)是相同的。为什么单冒号切片在Python 2.6上的工作方式与2.4版本相同?
python2.6的:
>>> a = array([[1,2,3],[4,5,6]])
**>>> a[:]
zeros((0, 3), 'l')**
>>> a[::]
array([[1,2,3],[4,5,6]])
>>> a[...]
array([[1,2,3],[4,5,6]])
的python2.4:
>>> a = array([[1,2,3],[4,5,6]])
**>>> a[:]
array([[1,2,3],[4,5,6]])**
>>> a[::]
array([[1,2,3],[4,5,6]])
>>> a[...]
array([[1,2,3],[4,5,6]])
(我从头开始输入&#34;代码&#34;因此它可能不是完全准确的语法或打印输出,但显示了正在发生的事情)
答案 0 :(得分:1)
似乎问题是整数溢出问题。在Numeric源代码中,正在使用的矩阵数据结构位于名为MA.py的文件中。特定的类称为MaskedArray。在类的末尾有一行设置&#34; array()&#34;这个班的功能。我很难找到这些信息,但事实证明这非常关键。
MaskedArray类中还有一个 getslice (self,i,j)方法,它接收开始/停止索引并返回正确的切片。在找到这些并为这些索引添加调试之后,我发现在Python2.4的良好情况下,当对整个数组进行切片时,自动输入的开始/停止索引分别为0和2 ^ 31-1。但是在Python2.6下,停止索引自动输入变为2 ^ 63-1。
某处,可能在数字源/库代码中,切片数组时只有32位来存储停止索引。因此,2 ^ 63-1值溢出(但任何大于2 ^ 31的值都会溢出)。在这些不良情况下的输出切片最终等同于从开始0到停止0的切片,例如,一个空矩阵。从[0:-1]切片时,您会获得有效切片。我认为(2 ^ 63 - 1)被解释为32位数将出现-1。我不太清楚为什么从0到2 ^ 63-1的切片输出与从0到0(你得到一个空矩阵)的切片相同,而不是从0到-1(你得到的地方)至少有一些输出)。
虽然,如果我输入会溢出的结束切片索引(即大于2 ^ 31),但是低32位是有效的正非零数,我将得到有效切片。例如。停止索引2 ^ 33 + 1将返回与停止索引1相同的切片,因为在这两种情况下,低32位都是1。
Python 2.4示例代码:
>>> a = array([[1,2,3],[4,5,6]])
>>> a[:] # (which actually becomes a[0:2^31-1])
[[1,2,3],[4,5,6]] # correct, expect the entire array
Python 2.6示例代码:
>>> a = array([[1,2,3],[4,5,6]])
>>> a[:] # (which actually becomes a[0:2^63-1])
zeros((0, 3), 'l') # incorrect b/c of overflow, should be full array
>>> a[0:0]
zeros((0, 3), 'l') # correct, b/c slicing range is null
>>> a[0:2**33+1]
[ [1,2,3]] # incorrect b/c of overflow, should be full array
# although it returned some data b/c the
# lower 32 bits of (2^33+1) = 1
>>> a[0:-1]
[ [1,2,3]] # correct, although I'm not sure why "a[:]" doesn't
# give this output as well, given that the lower 32
# bits of 2^63-1 equal -1
答案 1 :(得分:0)
我认为我10年前使用的是2.4。我当时使用了numpy
,但可能为其Numeric
功能添加了NETCDF
。但细节是模糊的。我现在没有任何版本用于测试。
当时的Python文档应该很容易探索。 numpy
/ Numeric
文档较为简洁。
我认为Python总是对列表进行基本的:
切片。 alist[:]
制作副本,alist[1:-1]
来分割第一个和最后一个元素等。
我不知道添加step
的时间,例如alist[::-1]
撤消列表。
Python开始根据数字开发人员的要求识别索引元组,例如: arr[2,4]
,arr[(2,4)]
,arr[:, [1,2]]
,arr[::-1, :]
。但我不知道什么时候出现
Ellipsis
也主要用于多维索引。 Python解释器识别...
,但列表不处理它。大约在同一时间:
符号正式实现为slice
,例如
在3.5中,我们可以使用slice
In [6]: list(range(10)).__getitem__(slice(None,None,-1))
Out[6]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
我会建议一些事情:
确保您了解当前系统中的numpy
(和list
)索引/切片
在旧版本中尝试相同的操作;用具体的差异例子问SO问题。不要指望我们中的任何人能够记住旧代码。
研究文档以查找何时更改或添加了可疑功能。