Python:如何读取列数不均匀的数据文件

9
我的朋友需要读取大量(大约18000个数据集)格式非常恼人的数据,这些数据应该是8列和~8000行,但实际上,数据以7列的形式呈现,最后一个条目会溢出到下一行的第一列。此外,每隔约30行只有4列数据,因为某个上游程序正在将200 x 280数组重塑为7x8120数组。我的问题是:我们如何将数据读入8x7000数组中。我的通常方法np.loadtxt和np.genfromtxt在列数不均匀的情况下失败。请记住,性能是一个因素,因为这必须对约18000个数据文件执行。以下是典型数据文件的链接:http://users-phys.au.dk/hha07/hk_L1.ref

澄清一下:每24行会有一个4列的行,因为八列会持续“溢出”到下一行。对吗?每个24*7+4的块都有200个项目,可以被8整除。 - Eduardo Ivanec
1
一个例子会非常有用。 - Adam Matan
1
修复上游程序以输出漂亮的HDF5文件,或者至少输出比这更合理的内容如何? - Sven Marnach
3个回答

12

我想到了一个更简单的方法:

with open("hk_L1.ref") as f:
    data = numpy.array(f.read().split(), dtype=float).reshape(7000, 8)

该代码首先将数据读取为一维数组,完全忽略所有换行符,然后将其重新塑形为所需形状。

虽然我认为这个任务无论如何都会受到I/O限制,但如果相关,这种方法应该使用很少的处理器时间。


1

如果我理解你的意思正确(请看我的评论),你可以将输入分成标记,然后无差别地以八个为一块进行处理:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

f = open('filename.ref')
tokens = f.read().split()

rows = []
for idx, token in enumerate(tokens):
    if idx % 8 == 0:
        # this is a new row, use a new list.
        row = []
        rows.append(row)
    row.append(token)

# rows is now a list of lists with the desired data.

这段代码在我的电脑上运行时间不到0.2秒。

编辑:采用了@SvenMarnach的建议。


你为什么要在这里使用 shlex?一个简单的 str.split() 就可以解决问题了。 - Sven Marnach
@SvenMarnach:我认为这种方法更简单,因为它可以从文件中呈现无尽的令牌流。如果使用line.split(),我将不得不自己迭代文件,并跟踪由OP描述的8列中的7个问题所导致的当前偏移量。要么这样,要么编写一个生成器,但这几乎就是我在这里使用shlex的方式。如果我理解有误,请告诉我! - Eduardo Ivanec
@SvenMarnach:你当然是正确的。我认为使用它是有意义的,因为它充当生成器(应该将内存使用减半),但显然并不是这样,这使它加快了20倍!谢谢。 - Eduardo Ivanec

0

这个怎么样?

data = []
curRow = []
dataPerRow = 8
for row in FILE.readlines():
    for item in row.split():
         if len(curRow) == dataPerRow:
             data.append(curRow)
             curRow = []
         curRow.Append(item)

data.append(curRow)

(假设 FILE 是被读取的文件) 然后你有一个列表的列表,可以用于任何事情。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接