首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python和数字/数字数组切片行为

Python和数字/数字数组切片行为
EN

Stack Overflow用户
提问于 2016-02-27 00:06:11
回答 2查看 242关注 0票数 0

在Python2.4上,单冒号片操作符:Numeric矩阵上按预期工作,因为它返回它所使用的维度的所有值。例如,二维矩阵的所有X和/或Y值.

在Python2.6上,单冒号切片操作符在某些情况下似乎有不同的效果:例如,在常规的二维MxN矩阵上,m[:]可能导致作为结果片返回zeros(<some shape tuple>, 'l')。完整的矩阵是人们所期望的--这就是我们使用Python2.4所得到的。

在Python2.6中使用双冒号::或3点... (而不是单个冒号)似乎解决了这个问题,并返回了正确的矩阵切片。

经过一些猜测,我发现当输入0作为停止索引时,可以获得相同的零输出。例如,m[<any index>:0]返回与m[:]相同的“零”输出。在尝试执行m[:]时,是否有任何方法来调试选择了哪些索引?还是在两个Python版本(2.4到2.6)之间发生了一些变化,从而影响了切片操作符的行为?

使用的Numeric版本(24.2)在这两个版本之间是相同的。为什么单冒号切片在Python2.6上的工作方式与2.4版本不同?

Python2.6 2.6:

代码语言:javascript
运行
复制
>>> 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:

代码语言:javascript
运行
复制
>>> 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]])

(我从头到尾输入了“代码”,所以它可能不是完全准确的语法,也不是打印出来的,而是显示了正在发生的事情)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-03 20:04:41

问题似乎是整数溢出问题。在数字源代码中,正在使用的矩阵数据结构位于一个名为MA.py的文件中。特定的类称为MaskedArray。类的末尾有一行将"array()“函数设置为该类。我很难找到这个信息,但事实证明它是非常关键的。

getslice(self,类中还有一个MaskedArray 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。

Python2.4示例代码:

代码语言:javascript
运行
复制
>>> 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

Python2.6示例代码:

代码语言:javascript
运行
复制
>>> 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
EN

Stack Overflow用户

发布于 2016-02-27 22:20:59

我想我10年前用的是2.4。我当时使用了numpy,但可能已经为其NETCDF功能添加了Numeric。但细节是模糊的。而我现在没有这些版本的测试。

那时的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反转列表

代码语言:javascript
运行
复制
In [6]: list(range(10)).__getitem__(slice(None,None,-1))
Out[6]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

我建议几件事:

  • 确保您理解当前系统中的numpy (和list)索引/切片
  • 在旧的版本中尝试同样的事情;问这样的问题,并给出具体的例子。不要指望我们中的任何人有旧代码的记忆。
  • 研究文档,以便在可疑的特征更改或添加时找到。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35663958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档