Python Numpy妨碍了int->;浮法铸造

Python Numpy妨碍了int->;浮法铸造,python,numpy,Python,Numpy,提前道歉-我似乎有一个根本性的误解,我无法澄清。我有一个fourvector类,包含ct和位置向量的变量。我正在编写代码来执行x方向的洛伦兹增强。我遇到的问题是,正如下面所写的,ct返回一个合适的浮点值,但是x没有。搞砸了,我发现tempx是一个浮点数,但将tempx赋给r[0]并不能使其成为浮点数,而是将其舍入为int。我之前曾发布过一个关于可变性与不可变性的问题,我怀疑这就是问题所在。如果是这样,我显然有一个比预期更深的误解。不管怎样,我有几个问题 1a)如果用a=FourVector(ct

提前道歉-我似乎有一个根本性的误解,我无法澄清。我有一个fourvector类,包含ct和位置向量的变量。我正在编写代码来执行x方向的洛伦兹增强。我遇到的问题是,正如下面所写的,ct返回一个合适的浮点值,但是x没有。搞砸了,我发现tempx是一个浮点数,但将tempx赋给r[0]并不能使其成为浮点数,而是将其舍入为int。我之前曾发布过一个关于可变性与不可变性的问题,我怀疑这就是问题所在。如果是这样,我显然有一个比预期更深的误解。不管怎样,我有几个问题

1a)如果用a=FourVector(ct=5,r=[55,2,3])实例化a,则类型(a._r[0])返回numpy.float64,而不是numpy.int32。这是怎么回事?我只希望a._r[1]是一个浮点,而它会改变整个列表的类型

1b)如何获得上述行为(整个列表都是浮点数),而不必将变量实例化为浮点数?我阅读了文档并尝试了各种方法,比如使用astype(float),但我所做的每件事似乎都将它保持为int。再次,我认为这是我遇到的可变/不可变问题

2) 我原以为,在节奏中。。。行乘以1.0会将其转换为浮点,因为这似乎是ct转换为浮点的原因,但由于某些原因,它不会。也许和其他人的原因一样

import numpy as np

class FourVector():
    def __init__(self, ct=0, x=0, y=0, z=0, r=[]):
        self._ct = ct
        self._r = np.array(r)
        if r == []:
            self._r = np.array([x,y,z])

    def boost(self, beta):
        gamma=1/np.sqrt(1-(beta ** 2))
        tempct=(self._ct*gamma-beta*gamma*self._r[0])
        tempx=(-1.0*self._ct*beta*gamma+self._r[0]*gamma)
        self._ct=tempct
        print(type(self._r[0]))
        self._r[0]=tempx.astype(float)
        print(type(self._r[0]))

a = FourVector(ct=5,r=[55,2,3])
b = FourVector(ct=1,r=[4,5,6])
print(a._r)
a.boost(.5)
print(a._r)

你所有的问题都是相关的

numpy数组是一种高效保存对象的数组。它通过使这些对象具有相同的类型来实现这一点,比如字符串(长度相等)或整数或浮点数。然后,它可以轻松地计算每个元素需要多少空间,以及访问下一个元素必须“跳转”多少字节(我们称之为“跨步”)

从列表中创建数组时,numpy将尝试从该列表中确定合适的数据类型(“dtype”),以确保所有元素都可以很好地表示。只有在显式指定数据类型时,它才不会做出有根据的猜测

考虑以下示例:

>>> import numpy as np
>>> integer_array = np.array([1,2,3])  # pass in a list of integers
>>> integer_array
array([1, 2, 3])
>>> integer_array.dtype
dtype('int64')
如您所见,在我的系统上,它返回的数据类型为
int64
,这是使用8个字节表示的整数。它选择这样做是因为:

  • numpy识别列表中的所有元素都是整数
  • 我的系统是64位系统
  • 现在考虑改变数组的尝试:

    >>> integer_array[0] = 2.4  # attempt to put a float in an array with dtype int
    >>> integer_array # it is automatically converted to an int!
    array([2, 2, 3])
    
    如您所见,一旦设置了数组的数据类型,就会自动转换到该数据类型。 现在让我们考虑当您在一个至少有一个浮动的列表中传递时发生了什么:

    >>> float_array = np.array([1., 2,3])
    >>> float_array
    array([ 1.,  2.,  3.])
    >>> float_array.dtype
    dtype('float64')
    
    numpy再次为该数组确定合适的数据类型

    盲目尝试更改数组的数据类型是不明智的:

    >>> integer_array.dtype = np.float32
    >>> integer_array
    array([  2.80259693e-45,   0.00000000e+00,   2.80259693e-45,
             0.00000000e+00,   4.20389539e-45,   0.00000000e+00], dtype=float32)
    
    你可能会说,这些数字是胡言乱语。这是因为numpy试图将该数组的内存位置重新解释为4字节浮点(技术人员将能够将数字转换为二进制表示,并从中重新解释原始整数值)

    如果要强制转换,则必须显式执行,numpy将返回一个新数组:

    现在,请回答您的具体问题:

    1a)如果用a=FourVector(ct=5,r=[55,2,3])实例化a,则类型(a._r[0])返回numpy.float64,而不是numpy.int32。这是怎么回事?我只希望a._r[1]是一个浮点,而它会改变整个列表的类型

    这是因为numpy必须为整个数组确定一个数据类型(除非使用a),以确保所有元素都适合该数据类型。只有这样,numpy才能有效地迭代该数组的元素

    1b)如何获得上述行为(整个列表都是浮点数),而不必将变量实例化为浮点数?我阅读了文档并尝试了各种方法,比如使用astype(float),但我所做的每件事似乎都将它保持为int。再次,我认为这是我遇到的可变/不可变问题

    创建数组时指定
    dtype
    。在您的代码中,这将是:

    self._r = np.array(r, dtype=np.float)
    
    2) 我原以为,在节奏中。。。行乘以1.0会将其转换为浮点,因为这似乎是ct转换为浮点的原因,但由于某些原因,它不会。也许和其他人的原因一样

    import numpy as np
    
    class FourVector():
        def __init__(self, ct=0, x=0, y=0, z=0, r=[]):
            self._ct = ct
            self._r = np.array(r)
            if r == []:
                self._r = np.array([x,y,z])
    
        def boost(self, beta):
            gamma=1/np.sqrt(1-(beta ** 2))
            tempct=(self._ct*gamma-beta*gamma*self._r[0])
            tempx=(-1.0*self._ct*beta*gamma+self._r[0]*gamma)
            self._ct=tempct
            print(type(self._r[0]))
            self._r[0]=tempx.astype(float)
            print(type(self._r[0]))
    
    a = FourVector(ct=5,r=[55,2,3])
    b = FourVector(ct=1,r=[4,5,6])
    print(a._r)
    a.boost(.5)
    print(a._r)
    
    这是真的。尝试打印
    tempx
    的数据类型,它应该是一个浮点数。但是,稍后,您会将该值重新插入到数组
    self.\r
    ,该数组的数据类型为int。正如您前面所看到的,这将浮点转换回整数类型