在Python中准确地将19位数字符串转换为数字

时间:2012-12-12 02:27:12

标签: python numpy

我有一个大型数据文件,其中的数字列由空格分隔。我想把它们作为一个numpy数组阅读。

我用numpy.loadtxt(filename)来读取文件。当代码试图将这个19位数的字符串转换为数字时出现问题;似乎它只能准确地代表前17位。

这是一个简化的例子:

from StringIO import StringIO
import numpy as np 

#use this s string to mimick the input txt file
s = StringIO('1237657220412736271 39843.3948')
arr = np.loadtxt(s)
print int(arr[0])

如果你运行它,你得到

1237657220412736256

我知道可以从np.loadtxt()指定您拥有的数据类型,但即使我指定它将第一个数字作为长整数读取,它仍然不能代表19位数的字符串数字准确。

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

  

即使我指定它读取第一个数字为长整数

好吧,鉴于您的第二个值是浮点数,我不确定您是如何使用单一类型执行此操作的。但拿走它,你可以读取第一个数字作为一个更长的整数类型,一切正常:

>>> s = cStringIO.StringIO('1237657220412736271 39843')
>>> arr = np.loadtxt(s, dtype='i8')
>>> int(arr[0])
1237657220412736271

同样,如果你指定一个异构格式,如('i8', 'f8')并输入原始字符串,那么原始字符串就可以正常工作。

所以,我怀疑你没有做你认为你做过的事情,这就是为什么它不起作用。

另一种可能性是,通过“长整数”,你的字面意思是“一个C长”,而你是在一个32位平台或64位Windows,这意味着一个32位数字。但我很确定numpy再次将这种类型带走了 - 如果不这样做,它会给你一个与你所看到的问题不同的问题。

答案 1 :(得分:1)

当您调用np.loadtxt时,假设文件中的所有元素都是浮点数。当您将其转换回整数时,这会导致精度问题。您可以在np.loadtxt中指定读取的结构化数组,这将使其能够读取具有不同数据类型的不同列:

arr = np.loadtxt(s, dtype={'names': ('ints', 'floats'),
                                     'formats': ('i8', 'f8')})

这里的区别在于您获得了结构化数组而不是给定数据类型的2D数组。您必须以不同的方式对其进行索引(通过名称或索引号),但您可以检查是否正确读取了整数:

>>> int(arr[0][0])
1237657220412736271
>>> int(arr['ints'][0])
1237657220412736271

(请注意,此语法将因您的特定字符串s而失败,因为它只有一行并且将提供0-d数组,但它适用于多行的文件。)

另一种方法是做两次np.loadtxt次加载,每列一次:

arr1 = np.loadtxt(s, dtype='i8', usecols=(0,))
arr2 = np.loadtxt(s, dtype='f8', usecols=(1,))

答案 2 :(得分:0)

我试过了:

>>> s = '1237657220412736271 39843.3948'
>>> a = s.split()
>>> int(a[0])
1237657220412736271

不幸的是,当numpy将19位数字作为浮点数读取时,没有足够的精度来获取所有有效数字,因此存在舍入误差。如果你知道这个数字总是适合int但是太大而不能完全用双精度表示,那么你可能需要做一些像我上面所做的那样来解决这个限制。< / p>