itertools不将numpy int识别为Python 3.6上的有效输入
以这个代码为例:itertools不将numpy int识别为Python 3.6上的有效输入,python,python-3.x,numpy,itertools,Python,Python 3.x,Numpy,Itertools,以这个代码为例: import itertools as it import numpy as np data = ['a','b','c','d'] dw = np.array([1, 3], dtype=np.int64) print(list(it.islice(data,dw[0],dw[1],1))) 在Python2.7上,它按预期打印['b','c',] 在Python 3.6上,它抛出一个异常: ValueError: Stop argument for islice() mu
import itertools as it
import numpy as np
data = ['a','b','c','d']
dw = np.array([1, 3], dtype=np.int64)
print(list(it.islice(data,dw[0],dw[1],1)))
在Python2.7上,它按预期打印['b','c',]
在Python 3.6上,它抛出一个异常:
ValueError: Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize.
ValueError:islice()的Stop参数必须为None或整数:0anumpy。int64
显然不是int
a, b = dw[0], dw[1]
类型(a)
isinstance(a,int)
Numpy文档
报告明确提到了这一点
警告
int_uu类型不是从Python 3下的int内置继承的,
因为int类型不再是固定宽度的整数类型
解决方案
还是裸体切片
data[dw[0]:dw[1]:1]
如果要保留类似的islice
/切片
-对象,请使用np.s
:
slice = np.s_[dw[0]: dw[1]: 1]
data[slice]
['b', 'c']
由于np.s\ucode>是一个numpy
对象,它不介意numpy
整数。我不确定它是否是Python 3中的一个bug,但它的行为似乎自2.7以来发生了变化。如前所述,在py27下,numpy.int32
或numpy.int64
似乎是int
的子类(取决于您使用的是32位还是64位的Python构建);在py3下,类型不再相关(numpy有固定宽度的数字类型,python的int
是可变宽度)
要求其参数是类型为PyLong()的对象。具体来说,它调用,将Python对象转换为Csize\t
值。这个方法似乎要求它的参数实际上是一个Pythonint
对象,因为它调用。我认为这个方法大致相当于Python的isinstance(obj,int)
,这解释了py2和py3之间的行为差异
使用另一种更宽容的方法将参数强制转换为正整数值,称为。
这将检查其参数是否为int
,如果不是,则返回到尝试调用其参数的方法;正如@MarkDickinson指出的,numpy的数值类型实现了这个方法,所以一切都很好。对于itertools.islice
来说,这可能是一件更直观的事情。这看起来像是\uuuuuuu索引
魔术方法(numpy的整数已经实现了)的一个例子。我建议在跟踪器上提出一个问题,作为一个增强请求——islice接受任何实现\uuuu index\uuu
常规切片的对象从来都不是问题<代码>列表(it.islice(data,np.s_dw[0]])
仍然失败。要点是跳过创建一个iterable
对象,并使用一个具有等效函数的numpy
对象。itertools
失败的原因在其他答案中有说明。因此,介绍性短语“如果你想保留一个切片状的对象”。i、 e.如果要在一堆不同的列表中使用该切片,那么为什么不直接使用slice()
像a=slice(dw[0],dw[1]);数据[a]
。因为当我尝试slice()
时,出现了一个完全不相关的错误,我假设它是相同的整数类型不匹配。哎呀<代码>np.s_[]
看起来还是不错,我想!那么为什么itertools.islice
需要int
s,而常规列表切片没有它们(例如data[dw[0]]
)就可以了?@Chris\u Rands:常规列表切片和索引支持任何实现\u index\u
方法的东西。NumPy整数类型实现了该方法。@MarkDickinson谢谢;这种设计有什么原因吗?为什么不让islice
也支持使用\uuuuu索引\uuuu
方法的任何东西呢?尽管考虑到转换到int
有多么容易,也许没有真正的必要这么做。@Chris\u Rands:我认为这是bugs.python.org的问题。@MarkDickinson好的,有一个bug问题已经提出了(不是由我提出的),因为像索引或布尔比较这样的事情很好,这不应该被认为是一个bug吗?显然,更多的基本功能是以一种有效的方式实现的。@Khris我个人倾向于认为这是islice
的一个缺点,是的。让islice
使用任何以某种方式“数值”的参数(例如,包括基类型np.integer
)似乎更明智。最简单的解决方法是使用类型转换:int(dw[0]),int(dw[1])
即使在它工作的地方,py2.7,使用数组而不是列表会更慢。正是那种让我讨厌Python的东西。
print(list(it.islice(data, int(dw[0]) , int(dw[1]), 1)))
data[dw[0]:dw[1]:1]
slice = np.s_[dw[0]: dw[1]: 1]
data[slice]
['b', 'c']