我可以想到两种方法来提供您要求的一些功能:
要以块 / 或 n 行 / 等的方式读取文件:
您可以将 a 传递generator
给numpy.genfromtxt以及numpy.loadtxt。通过这种方式,您可以高效地从文本文件中加载大型数据集,同时保留这两个函数的所有便捷解析功能。
要仅从与可以表示为正则表达式的标准匹配的行中读取数据:
您可以使用numpy.fromregex并使用 aregular expression
来精确定义应加载输入文件中给定行中的哪些标记。与模式不匹配的行将被忽略。
为了说明这两种方法,我将使用我的研究背景中的一个例子。
我经常需要加载具有以下结构的文件:
6
generated by VMD
CM 5.420501 3.880814 6.988216
HM1 5.645992 2.839786 7.044024
HM2 5.707437 4.336298 7.926170
HM3 4.279596 4.059821 7.029471
OD1 3.587806 6.069084 8.018103
OD2 4.504519 4.977242 9.709150
6
generated by VMD
CM 5.421396 3.878586 6.989128
HM1 5.639769 2.841884 7.045364
HM2 5.707584 4.343513 7.928119
HM3 4.277448 4.057222 7.022429
OD1 3.588119 6.069086 8.017814
这些文件可能很大(GB),我只对数字数据感兴趣。所有数据块都具有相同的大小——6
在这个例子中——它们总是被两行分隔。所以stride
块的 是8
。
使用第一种方法:
首先,我将定义一个过滤掉不需要的行的生成器:
def filter_lines(f, stride):
for i, line in enumerate(f):
if i%stride and (i-1)%stride:
yield line
然后我打开文件,创建一个filter_lines
-generator(这里我需要知道stride
),然后将该生成器传递给genfromtxt
:
with open(fname) as f:
data = np.genfromtxt(filter_lines(f, 8),
dtype='f',
usecols=(1, 2, 3))
这就像轻而易举。请注意,我可以用来usecols
删除数据的第一列。同样,您可以使用所有其他功能genfromtxt
——检测类型、从列到列的不同类型、缺失值、转换器等。
在此示例data.shape
中(204000, 3)
,原始文件由272000
行组成。
在这里,generator
它用于过滤均匀跨度的线条,但同样可以想象它根据(简单)标准过滤掉不均匀的线条块。
使用第二种方法:
这是regexp
我要使用的:
regexp = r'\s+\w+' + r'\s+([-.0-9]+)' * 3 + r'\s*\n'
组——即内部()
——定义要从给定行中提取的标记。接下来,fromregex
完成这项工作并忽略与模式不匹配的行:
data = np.fromregex(fname, regexp, dtype='f')
结果与第一种方法完全相同。