从非常规文本文件中提取信息? (Python)的

时间:2017-03-09 03:20:07

标签: python arrays io

我正在尝试从协作者发送给我的一组文件中提取一些信息。每个文件都包含一些python代码,用于命名列表序列。他们看起来像这样:

#PHASE = 0
x = np.array(1,2,...)
y = np.array(3,4,...)
z = np.array(5,6,...)

#PHASE = 30
x = np.array(1,4,...)
y = np.array(2,5,...)
z = np.array(3,6,...)

#PHASE = 40
...

等等。总共有12个文件,每个文件有7个相位集。我的目标是将每个阶段转换为它自己的文件,然后由ascii.read()作为Table对象读取,以便在不同的代码段中进行操作。

我目前的方法在资源和组装所需的时间/能量方面效率极低。它是这样的:从函数开始

def makeTable(a,b,c):
   output = Table()
   output['x'] = a
   output['y'] = b
   output['z'] = c
   return output

然后对于每个阶段,我手动将文本文件的相关部分复制粘贴到单元格中并附加一行代码

fileName_phase = makeTable(a,b,c)

重复广告恶心。这将需要84次迭代来处理所有数据,当然每个都需要一些微小的调整来匹配特定的fileName和阶段。

最后,在我的代码结束时,我将几行代码设置为ascii。将每个表写入.dat文件以供以后操作。

整个方法设置非常耗费精力。如果它是处理数据的唯一方法,我会这样做。但是,我希望我能找到一种更快捷的方式进行设置。你可以建议吗?

3 个答案:

答案 0 :(得分:1)

如果目标是效率和代码重用而不是复制,我认为Classes可能提供了一个好方法。我现在要睡觉了,但我稍后会编辑。这是我的想法:创建一个名为FileWithArrays的类,并使用解析器读取行并将它们放入您将使用该类创建的对象FileWithArrays中。完成后,您可以创建一个方法来转换表中的对象。

P.S。解析器的一个好主意是将所有行存储在列表中并逐个解析它们,使用list.pop()自动收缩列表。希望它有所帮助,明天我会更多地看它,如果这没有多大帮助。如果我误解了任何东西,尝试重写/重新格式化问题,这不是很容易阅读。

答案 1 :(得分:1)

我会建议一种可以被许多人嘲笑的方法,但会完成你的工作。

向每个人道歉。

此方法的先决条件是您完全信任输入文件的正确性。我想你做的。 (毕竟他是你的合作者)。

所以这里的关键点是文件中的文本是代码,这意味着它可以被执行。

所以你可以做这样的事情

import re
import numpy as np # this is for the actual code in the files. You might have to install numpy library for this to work.
file = open("xyz.txt")
content = file.read()

现在您已拥有所有内容,您必须按阶段将其分开。 为此,我们将使用re.split函数。

phase_data = re.split("#PHASE = .*\n", content)

现在我们有一个数组中每个阶段的内容。

现在是执行它的部分。

for phase in phase_data:
    if len(phase.strip()) == 0:
        continue
    exec(phase)
    table = makeTable(x, y, z) # the x, y and z are defined by the exec. 
    # do whatever you want with the table.

我将重申您必须完全信任该文件的内容。因为你将它作为代码执行。

但是你的作品看起来像是一个脚本,我相信这会让你的工作完成。

PS:另一个更安全" exec的替代方法是有一个沙盒库,它接受字符串并执行它而不影响父范围。

答案 2 :(得分:1)

为避免@Ajay Brahmakshatriya建议使用exec的安全问题,但保留他的第一个处理步骤,您可以创建自己的最小阶段解析器,例如:

VARS = 'xyz'
def makeTable(phase):
    assert len(phase) >= 3
    output = Table()
    for i in range(3):
        line = [s.strip() for s in phase[i].split('=')]
        assert len(line) == 2
        var, arr = line
        assert var == VARS[i]
        assert arr[:10]=='np.array([' and arr[-2:]=='])'
        output[var] = np.fromstring(arr[10:-2], sep=',')
    return output

然后致电

table = makeTable(phase)

而不是

exec(phase)
table = makeTable(x, y, z)

您还可以跳过所有这些assert语句而不会影响安全性,如果文件已损坏或未按预期格式化,则会抛出的错误可能更难理解......