0

我有一个大数据文件,其中的数字列由空格分隔。我想将它们作为一个 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 位数字字符串。

有没有更好的方法来做到这一点?

4

3 回答 3

2

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

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

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

同样,如果您指定异构格式,例如('i8', 'f8')并输入原始字符串,则可以很好地处理原始字符串。

所以,我怀疑你没有做你认为你做的事,这就是为什么它没有奏效。

另一种可能性是,“长整数”的字面意思是“C long”,并且您使用的是 32 位平台或 64 位 Windows,这意味着 32 位数字。但我敢肯定numpy,这种类型又被淘汰了很久——而且,如果他们不这样做,它会给你带来与你所看到的不同的问题。

于 2012-12-12T02:40:30.390 回答
1

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

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

这里的区别是你得到一个结构化数组而不是给定数据类型的二维数组。您必须以不同的方式对其进行索引(按名称或索引号),但您可以检查整数是否被正确读取:

>>> 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,))
于 2012-12-12T02:49:41.933 回答
0

我试过这个:

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

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

于 2012-12-12T02:42:42.867 回答