跨度 您可以将传递generator
给numpy.genfromtxt以及numpy.loadtxt。这样,您可以有效地从文本文件中加载大型数据集,同时保留两个函数的 便捷解析功能。
可以使用numpy.fromregex并使用regular 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')
结果与第一种方法完全相同。