【问题标题】:Python range with np.intc带有 np.intc 的 Python 范围
【发布时间】:2021-01-29 09:46:18
【问题描述】:

昨天我在这里问了一个关于 python range() 的奇怪行为的问题。 我不小心使用了range() 而不是np.arange()。但视情况而定 输入 int-type 它是否适用于数学运算。 这是在一个巨大的背景下,所以我简化了这个问题。

import numpy as np 

"""
DOES WORK
"""
x1 = np.intc(545)
x2 = np.intc(1048)
x_axis = range(x1, x2) 
test = (x_axis - x1) # should throw exception, but works
type(x_axis[0]) # numpy.int32 / intc

"""
DOESNT WORK
"""
t1 = 545
t2 = 1048
t_axis = range(t1, t2)
test2 = (t_axis - t1) # throws TypeError unsupported operand type(s) for -: 'range' and 'int'

背景: 使用 intc-datatype 的原因是我的程序执行了一些其他任务,例如寻峰等,并且我使用一些列表理解来从计算的峰值中生成列表。在其他一些步骤之后,我使用了这个峰值列表中的 x1 和 x2(这显然不是一个正常的整数列表)。所以我昨天更改了我的代码并生成了一个新列表,然后发生了异常。我的猜测是 numpy/scipy 在内部使用 intc。

谁能解释这种行为?

【问题讨论】:

    标签: python numpy integer range


    【解决方案1】:

    Python 序列和标量的行为不同于 numpy 一维数组和标量。让我们通过几个基本示例来了解它(如果赶时间的话,可以直接跳到底部):

    # define our test objects
    a_range = range(2,6)
    a_list = list(a_range)
    a_array = np.array(a_list)
    
    # ranges don't add
    a_range+a_range
    # Traceback (most recent call last):
    #   File "<stdin>", line 1, in <module>
    # TypeError: unsupported operand type(s) for +: 'range' and 'range'
    
    # lists do add but with different semantics ...
    a_list+a_list
    # [2, 3, 4, 5, 2, 3, 4, 5]
    
    # ... from numpy arrays
    a_array+a_array
    # array([ 4,  6,  8, 10])
    
    # what happens if we mix types?
    
    # range and list don't mix:
    a_range+a_list
    # Traceback (most recent call last):
    #   File "<stdin>", line 1, in <module>
    # TypeError: unsupported operand type(s) for +: 'range' and 'list'
    
    # but as soon as there is a numpy object involved it "wins":
        
    a_range+a_array
    # array([ 4,  6,  8, 10])
    
    a_list+a_array 
    # array([ 4,  6,  8, 10])
    
    # How about scalars?
    
    py_scalar = 3
    np_scalar = np.int64(py_scalar)
    
    # again, in pure python you cannot add something to a range ...
    a_range+py_scalar
    # Traceback (most recent call last):
    #   File "<stdin>", line 1, in <module>
    # TypeError: unsupported operand type(s) for +: 'range' and 'int'
    
    # or a list
    a_list+py_scalar
    # Traceback (most recent call last):
    #   File "<stdin>", line 1, in <module>
    # TypeError: can only concatenate list (not "int") to list
    
    # but you can add a Python or numpy scalar to a numpy object
    a_array+py_scalar
    # array([5, 6, 7, 8])
    
    a_array+np_scalar
    # array([5, 6, 7, 8])
    
    # Now if the scalar is a numpy object, again, it "wins":
    
    a_range+np_scalar
    # array([5, 6, 7, 8])
    
    a_list+np_scalar
    # array([5, 6, 7, 8])
    

    总而言之,Python 序列和 numpy 一维数组具有不同的语义,特别是对于像“+”、“-”或“*”这样的二元运算符。如果至少一个操作数是 numpy 对象(数组或标量),则 numpy 获胜:将转换非 numpy 对象(平面序列变为 1d 数组)并应用 numpy 语义。

    【讨论】:

    • 感谢您的详细回复!现在我对这种行为有了更多的了解;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 2017-11-30
    相关资源
    最近更新 更多