在python中使用大索引(numpy或list)

在python中使用大索引(numpy或list),python,numpy,Python,Numpy,我经常需要输入大整数来索引和创建numpy数组,例如3500000或250000。通常情况下,我会使用科学符号3.5e6或.25e6或诸如此类的符号输入。这会更快,而且出错的可能性也更小 不幸的是,python需要整数数据类型进行索引。显而易见的解决方案是转换数据类型。因此,[5e5:1e6]变成了[int(5e5):int(1e6)],但这会降低可读性,而且打字时间会更长。更不用说,在列表或numpy.ndarray上的索引操作失败之前,很容易忘记索引的数据类型 有没有一种方法可以让numpy

我经常需要输入大整数来索引和创建numpy数组,例如3500000或250000。通常情况下,我会使用科学符号3.5e6或.25e6或诸如此类的符号输入。这会更快,而且出错的可能性也更小

不幸的是,python需要整数数据类型进行索引。显而易见的解决方案是转换数据类型。因此,
[5e5:1e6]
变成了
[int(5e5):int(1e6)]
,但这会降低可读性,而且打字时间会更长。更不用说,在
列表
numpy.ndarray
上的索引操作失败之前,很容易忘记索引的数据类型


有没有一种方法可以让
numpy
或python将大浮点解释为整数,或者有没有一种简单的方法可以在python中创建大整数?

您可以为
int()
添加一个较短的名称,例如
I

I = int

x = I(3.5e6)
print (x)
#3500000

这仍然允许使用
int()

I = int

x = I(3.5e6)
print (x)
#3500000

这仍然允许正常使用
int()

如果您担心零的数量有误,请尝试下划线

>>> 3_500_000
3500000

如果您担心零的数量错误,请尝试下划线

>>> 3_500_000
3500000

我可以建议使用这样的符号
[5*10**5:1*10**6]
,但它不像5e5和1e6那样清晰。在
3.5e6=35*10**5
的情况下,更糟糕的是,我可以建议使用这种符号
[5*10**5:1*10**6]
,但它不像5e5和1e6那样清晰。更糟糕的是,在您考虑将
e5=10**5

作为
35*e5
中使用的
3.5e6=35*10**5
的注释中,遗憾地指出它不支持
3.5*e6
。这里有一个黑客可以做到:

class E:
    def __init__(self, e):
        self.val = 10**e
    def __rmul__(self, x):
        return int(x * self.val)
演示:

虽然由于浮动有损,但这可能会导致轻微的误差,例如:

>>> 0.1251*e6
125099
这里有一个更好的方法,构建文本
'0.1251e6'
,并对其进行评估:

class E:
    def __init__(self, e):
        self.e = e
    def __rmul__(self, x):
        return int(float('%se%d' % (x, self.e)))
演示:


在您考虑将
e5=10**5
用作
35*e5
的注释中,您感叹它不支持
3.5*e6
。这里有一个黑客可以做到:

class E:
    def __init__(self, e):
        self.val = 10**e
    def __rmul__(self, x):
        return int(x * self.val)
演示:

虽然由于浮动有损,但这可能会导致轻微的误差,例如:

>>> 0.1251*e6
125099
这里有一个更好的方法,构建文本
'0.1251e6'
,并对其进行评估:

class E:
    def __init__(self, e):
        self.e = e
    def __rmul__(self, x):
        return int(float('%se%d' % (x, self.e)))
演示:


我的廉价解决方案是在适当的范围内创建一个helper函数

def e(coeff, exponent):
    return int (coeff * 10 ** exponent)
np_array[e(3.5,6)] # use like this
但这个更便宜的答案可能会导致舍入误差, 在适当的范围内为int创建别名是一个简单而干净的解决方案

e=int # in proper scope

我的廉价解决方案是在适当的范围内创建一个helper函数

def e(coeff, exponent):
    return int (coeff * 10 ** exponent)
np_array[e(3.5,6)] # use like this
但这个更便宜的答案可能会导致舍入误差, 在适当的范围内为int创建别名是一个简单而干净的解决方案

e=int # in proper scope

这将解决索引列表和带有浮动的数组的问题

slice_orig = slice
def slice(*args):
    return slice_orig(*[int(i) for i in args])

slice.__doc__ = slice_orig.__doc__+ """
WARNING: overridden to convert (stop, start, step) to integers"""
它不允许在需要
int
类型的其他
numpy
函数中使用大数


编辑:这必须明确使用,例如
list[slice(1e5)]
,因此它没有我预期的那么有用。

这应该可以解决索引列表和带浮动的数组的问题

slice_orig = slice
def slice(*args):
    return slice_orig(*[int(i) for i in args])

slice.__doc__ = slice_orig.__doc__+ """
WARNING: overridden to convert (stop, start, step) to integers"""
它不允许在需要
int
类型的其他
numpy
函数中使用大数



编辑:这必须明确使用,例如
list[slice(1e5)]
,所以它没有我想象的那么有用。

你担心什么样的“错误”?@Stefan,主要是把
3500000
3500000
混淆。嗯?这两个都是一样的。你是在交互模式下使用这些索引,还是在你的程序中使用硬编码索引?哎呀,就是这样。我的意思是给一加上一个额外的零。你担心什么样的“错误”?Stefan,主要是把
3500000
3500000
搞混了?这两个都是一样的。你是在交互模式下使用这些索引,还是在你的程序中使用硬编码索引?哎呀,就是这样。我的意思是增加一个额外的0到1。这是一个很棒的解决方案,尽管我不敢在任何我需要了解指数的地方使用它。可以更清楚地预定义一些常量,例如
e5=10**5
e4=10**4
,等等。这将使
3.5e6=35*e5
。唯一的缺点是左边不能有小数点。是的,我认为5*e5更可读。我必须自己来解决这个问题:)这是一个很棒的解决方案,尽管我不敢在任何需要了解指数的地方使用它。可以更清楚地预定义一些常量,例如
e5=10**5
e4=10**4
,等等。这将使
3.5e6=35*e5
。唯一的缺点是左边不能有小数点。是的,我认为5*e5更可读。我必须自己来解决这个问题:)我喜欢它,它清晰易读,尽管有点冗长。此外,它似乎仅在python 3.6+中可用。也许是时候升级了。我喜欢它,它清晰易读,虽然有点冗长。此外,它似乎仅在python 3.6+中可用。也许是时候升级了。我不知道如何在python中更改literal的计算或创建reader宏,所以我几乎使用helper函数来缩短表达式或语句。这是不准确的,例如
e(0.1251,6)
是125099而不是125100。嗯。。。如果他们愿意在这个问题上使用
e
这个名字,并且像那样使用它,他们也可以只做
e=int
,然后像
e(3.5e6)
那样使用它。舍入错误对于这个用例来说至关重要,我尝试替换我的答案。是的,我觉得你说的答案很好。为int创建别名。我不知道如何在python中更改literal的计算或创建reader宏,所以我几乎使用helper函数来缩短表达式或语句