NumPy:从字符串列表加载异构数据列

2 投票
1 回答
844 浏览
提问于 2025-04-16 15:42

我正在处理存储在ASCII文件中的数组数据(类似于这个讨论)。我的文件至少有200万行(158 MB),并且分成多个部分,每个部分的格式都不一样。在我的模块中,我想通过lines = open('myfile.txt', 'r').readlines()一次性读取整个文件,这样我就可以找到每个部分的位置,然后把需要的部分读入NumPy的数据结构中。

比如,某个部分的内容是:

>>> print lines[5:10]
['      1 0.1000 0.300E-03 0.000E+00 0.300E-03 0.000E+00 0.000E+00 0.300E-03 0.100E-03\n', 
'      2 0.1000 0.120E-02 0.000E+00 0.120E-02 0.000E+00 0.000E+00 0.120E-02 0.100E-03\n', 
'      3 0.1000 0.100E-02 0.000E+00 0.100E-02 0.000E+00 0.000E+00 0.100E-02 0.100E-03\n', 
'      4 0.1000 0.110E-02 0.000E+00 0.110E-02 0.000E+00 0.000E+00 0.110E-02 0.100E-03\n', 
'      5 0.1000 0.700E-03 0.000E+00 0.700E-03 0.000E+00 0.000E+00 0.700E-03 0.100E-03\n']

这个部分的格式是[int, float, float, float, float, float, float, float, float],而后面的部分会有一个更简单的[int, float]格式:

>>> print lines[20:25]
['       1         0.00000E+00\n',
'       2         0.43927E-07\n',
'       3         0.44006E-07\n',
'       4         0.44020E-07\n',
'       5         0.44039E-07\n']

我该如何快速用NumPy加载不同部分的行呢?我看到有np.loadtxt,但它需要一个文件句柄,并且会一直读取到文件末尾。我也看到了np.from*函数,但我不太确定如何用我已经读取的lines来使用它们。我需要读取文件两次吗?

关于不同的数据类型,我想我可以使用一个复合dtype,比如np.dtype([('col1', '<i2'), ('col2', 'f4'), ('col3', 'f4'), ('col4', 'f4'), ('col5', 'f4'), ('col6', 'f4'), ('col7', 'f4'), ('col8', 'f4'), ('col9', 'f4')]),对吗?

1 个回答

3

StringIO 可以把字符串变成像文件一样的对象。这样你就可以这样做:

from StringIO import StringIO
m = np.loadtxt(StringIO('\n'.join(lines[5:10])))

或者更简单的,你可以直接这样做:

m = np.fromiter(lines[5:10],np.dtype([('col1', '<i2'), ('col2', 'f4'), ('col3', 'f4')]))

撰写回答