等同于Matlab的textscan的Pythonic

时间:2018-07-17 15:06:50

标签: python matlab

有一些与此类似的问题,但我找不到确切的答案。

我有一个非常奇怪的文本文件,其内容如下:

examine_vertex

Matlab的 field1=1; field2=2; field3=3; field1=4; field2=5; field3=6; 函数可以非常巧妙地处理此问题,您可以这样做:

textscan()

,您将返回一个单元格数组,其中每一列都包含各自的字段,而文本将被忽略。

我想用Python重写处理此文件的代码,但是Numpy的 array = textscan(fid, 'field1=%d; field2=%d; field3=%d;' loadtxt()似乎没有这种能力来忽略散布有所需数字的文本? / p>

有什么Python方法可以去除文本并仅取回字段?如果需要,我很高兴使用genfromtxt()或其他库。谢谢!

编辑:建议使用This问题作为答案,但是它仅等效于pandas的基本用法,该基本用法不处理输入中不需要的文本。以下是我需要的textscan答案。

2 个答案:

答案 0 :(得分:2)

Numpy的fromregex函数与textscan基本相同。它使您可以基于正则表达式读入,并使用组(由()包围的部分)作为值。这适用于您的示例:

data = np.fromregex('temp.txt', r'field1=(\d+); field2=(\d+); field3=(\d+);', dtype='int')

您也可以使用loadtxt。有一个参数converters,可让您提供执行从文本到数字的实际转换的函数。您可以提供一个功能,只需提供一个功能即可删除不需要的文本。

因此,在我的测试中,该方法有效:

myconv = lambda x: int(x.split(b'=')[-1])
mycols = [0, 1, 2]
convdict = {i: myconv for i in mycols}
data = np.loadtxt('temp.txt', delimiter=';', usecols=mycols, converters=convdict)

myconv是一个匿名函数,它接受一个值(例如'field1=1'),并在符号'='上拆分(使['field1', '1']), takes the last result ('1'{{1} } 1.`)。

), the converts that to a float (只是您要保留的列数。由于每行末尾都有一个定界符,因此将其视为空列。因此,我们将其排除在外。

mycols是一个字典,其中每个键是一个列号,每个值是将该列转换为数字的函数。在这种情况下,它们都是相同的,但是您可以根据需要自定义它们。

答案 1 :(得分:0)

Python与Matlab的textscan不完全相同(编辑:,但numpy具有fromregex。有关更多信息,请参见@TheBlackCat的answer。)

使用更复杂的格式,正则表达式可以完成工作。

import re

line_pat = re.compile(r'field1=(\d+); field2=(\d+); field3=(\d+);')
with open(filepath, 'r') as f:
    array = [[int(n) for n in line_pat.match(line).groups()] for line in f]