我有一个大型数据文件,其中的数字列由空格分隔。我想把它们作为一个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位数的字符串数字准确。
有更好的方法吗?
答案 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>