numpy妨碍int->浮式铸件 [英] Numpy getting in the way of int -> float type casting

查看:63
本文介绍了numpy妨碍int->浮式铸件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

提前道歉-我似乎有一个非常根本的误解,就是我无法清除.我有一个带有ct和位置向量变量的fourvector类.我正在编写代码以执行x方向的Lorentz增强.我遇到的问题是,正如下面所写,我返回的ct具有正确的浮点值,但是x却没有.乱七八糟,我发现tempx是一个浮点数,但是将tempx分配给r [0]并不会使它变成一个浮点数,而是将其四舍五入为一个int.我之前曾发布过关于可变性与不可变性的问题,我怀疑这是问题所在.如果是这样,我显然会比预期的有更深的误解.无论如何,我有几个问题;

Apologies in advance - I seem to be having a very fundamental misunderstanding that I can't clear up. I have a fourvector class with variables for ct and the position vector. I'm writing code to perform an x-direction lorentz boost. The problem I'm running in to is that I, as it's written below, ct returns with a proper float value, but x does not. Messing around, I find that tempx is a float, but assigning tempx to r[0] does not make that into a float, instead it rounds down to an int. I have previously posted a question on mutability vs immutability, and I suspect this is the issue. If so I clearly have a deeper misunderstanding than expected. Regardless, there are a couple of questions I have;

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

1a) If instantiate a with a = FourVector(ct=5,r=[55,2.,3]), then type(a._r[0]) returns numpy.float64 as opposed to numpy.int32. What is going on here? I expected just a._r[1] to be a float, and instead it changes the type of the whole list?

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

1b) How do I get the above behaviour (The whole list being floats), without having to instantiate the variables as floats? I read up on the documentation and have tried various methods, like using astype(float), but everything I do seems to keep it as an int. Again, thinking this is the mutable/immutable problem I'm having.

2)我曾想过,在tempx = ...行中,乘以1.0会将其转换为浮点数,因为这似乎是ct转换为浮点数的原因,但出于某些原因却没有.也许与其他原因相同?

2) I had thought, in the tempx=... line, multiplying by 1.0 would convert it to a float, as it appears this is the reason ct converts to a float, but for some reason it doesn't. Perhaps the same reason as the others?

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)

推荐答案

您的所有问题确实都与之相关.

All your problems are indeed related.

numpy数组是有效保存对象的数组.通过使这些对象具有相同的 type (例如长度相等的字符串或整数或浮点数)来实现此目的.然后,它可以轻松地计算出每个元素需要多少空间,以及它必须跳转"多少字节才能访问下一个元素(我们称这些为步幅").

A numpy array is an array that holds objects efficiently. It does this by having these objects be of the same type, like strings (of equal length) or integers or floats. It can then easily calculate just how much space each element needs and how many bytes it must "jump" to access the next element (we call these the "strides").

当您从列表中创建数组时,numpy会尝试从该列表中确定合适的数据类型("dtype"),以确保可以很好地表示所有元素.仅当您明确指定dtype时,它才会做出有根据的猜测.

When you create an array from a list, numpy will try to determine a suitable data type ("dtype") from that list, to ensure all elements can be represented well. Only when you specify the dtype explicitly, will it not make an educated guess.

请考虑以下示例:

>>> 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个字节的整数.之所以选择它,是因为:

As you can see, on my system it returns a data type of int64, which is a representation of integers using 8 bytes. It chooses this, because:

  1. numpy识别列表中的所有元素都是整数
  2. 我的系统是64位系统

现在考虑尝试更改该数组:

Now consider an attempt at changing that array:

>>> 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])

如您所见,设置数组的数据类型后,将自动转换为该数据类型. 现在让我们考虑一下,当您传递至少包含一个浮点数的列表时会发生什么:

As you can see, once a datatype for an array was set, automatic casting to that datatype is done. Let's now consider what happens when you pass in a list that has at least one float:

>>> float_array = np.array([1., 2,3])
>>> float_array
array([ 1.,  2.,  3.])
>>> float_array.dtype
dtype('float64')

再次,numpy为该数组确定合适的数据类型.

Once again, numpy determines a suitable datatype for this array.

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

Blindly attempting to change the datatype of an array is not wise:

>>> 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字节的浮点数(技术人员将能够将数字转换为二进制表示形式,然后从中重新解释原始的整数值).

Those numbers are gibberish you might say. That's because numpy tries to reinterpret the memory locations of that array as 4-byte floats (the skilled people will be able to convert the numbers to binary representation and from there reinterpret the original integer values).

如果要投射,则必须显式执行,并且numpy将返回一个 new 数组:

If you want to cast, you'll have to do it explicitly and numpy will return a new array:

>>> integer_array.dtype = np.int64 # go back to the previous interpretation
>>> integer_array
array([2, 2, 3])
>>> integer_array.astype(np.float32)
array([ 2.,  2.,  3.], dtype=float32)

现在,要解决您的特定问题:

Now, to address your specific questions:

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

1a) If instantiate a with a = FourVector(ct=5,r=[55,2.,3]), then type(a._r[0]) returns numpy.float64 as opposed to numpy.int32. What is going on here? I expected just a._r[1] to be a float, and instead it changes the type of the whole list?

那是因为numpy必须确定整个数组的数据类型(除非您使用

That's because numpy has to determine a datatype for the entire array (unless you use a structured array), ensuring all elements fit in that datatype. Only then can numpy iterate over the elements of that array efficiently.

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

1b) How do I get the above behaviour (The whole list being floats), without having to instantiate the variables as floats? I read up on the documentation and have tried various methods, like using astype(float), but everything I do seems to keep it as an int. Again, thinking this is the mutable/immutable problem I'm having.

在创建阵列时指定dtype.在您的代码中,应该是:

Specify the dtype when you are creating the array. In your code, that would be:

self._r = np.array(r, dtype=np.float)

2)我曾想过,在tempx = ...行中,乘以1.0会将其转换为浮点数,因为这似乎是ct转换为浮点数的原因,但出于某些原因却没有.也许与其他原因相同?

2) I had thought, in the tempx=... line, multiplying by 1.0 would convert it to a float, as it appears this is the reason ct converts to a float, but for some reason it doesn't. Perhaps the same reason as the others?

是的.尝试打印tempx的数据类型,它应该是浮点数.但是,稍后,您需要将该值重新插入具有dtype为int的数组self._r中.如您先前所见,这会将浮点数转换回整数类型.

That is true. Try printing the datatype of tempx, it should be a float. However, later on, you are reinserting that value into the array self._r, which has the dtype of int. And as you saw previously, that will cast the float back to an integer type.

这篇关于numpy妨碍int->浮式铸件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆