1

我有一个 .txt 文件,如下所示:

abcd this is the header
more header, nothing here I need
***********
column1    column2
=========  =========
  12.4       A
  34.6       mm
  1.3        um
=====================
footer, nothing that I need here
***** more text ******

我正在尝试读取列中的数据,每一个都进入它自己的列表,col1 = [12.4, 34.6, 1.3] 和 col2 = ['A', 'mm', 'um']。

这是我到目前为止所拥有的,但是当我运行代码时唯一返回的是“无”:

def readfile():
    y = sys.argv[1]

    z = open(y)
    for line in z:

        data = False
        if data == True:
            toks = line.split()
            print toks

        if line.startswith('=========  ========='):
            data = True
            continue

        if line.startswith('====================='):
            data = False
            break
print readfile()

有什么建议么?

4

3 回答 3

1

有很多方法可以做到这一点。

一种方法包括:

  1. 将文件读入行
  2. 从读取的行中,找到包含列标题分隔符的行的索引(因为这也与页脚标题匹配)。
  3. 然后,在这些行之间存储数据。
  4. 通过基于空格拆分这些行并将它们存储到各自的列中来解析这些行。

像这样:

with open('data.dat', 'r') as f:
    lines = f.readlines()

    #This gets the limits of the lines that contain the header / footer delimiters
    #We can use the Column header delimiters double-time as the footer delimiter:
    #`=====================` also matches against this.
    #Note, the output size is supposed to be 2. If there are lines than contain this delimiter, you'll get problems
    limits = [idx for idx, data in enumerate(lines) if '=========' in data]

    #`data` now contains all the lines between these limits
    data = lines[limits[0]+1:limits[1]] 

    #Now, you can parse the lines into rows by splitting the line on whitespace
    rows = [line.split() for line in data]

    #Column 1 has float data, so we convert the string data to float
    col1 = [float(row[0]) for row in rows]

    #Column 2 is String data, so there is nothing further to do
    col2 = [row[1] for row in rows]

    print col1, col2

这输出(来自您的示例):

[12.4, 34.6, 1.3] #Column 1
['A', 'mm', 'um'] #Column 2
于 2013-11-08T00:15:57.497 回答
0

您采用的方法可能不是很有效,但它有点错误,因此您的数据提取错误。

您需要在 &data之后立即触发 boolen ie line.startswith('========= ========='),直到那时它应该被保留False

在那里,您的数据将被提取,直到line.startswith('=====================').

希望我说对了。

def readfile():
    y = sys.argv[1]
    toks = []
    with open(y) as z:
        data = False

        for line in z:

            if line.startswith('=========  ========='):
                data = True
                continue

            if line.startswith('====================='):
                data = False
                break

            if data:
                toks.append(line.split())
                print toks
    col1, col2 = zip(*toks) # Or just simply, return zip(*toks)
    return col1, col2

print readfile()

with语句比z = open(file).

于 2013-11-08T00:09:18.070 回答
0

如果您知道文件有多少行页眉/页脚,则可以使用此方法。

path = r'path\to\file.csv'
header = 2
footer = 2
buffer = []

with open(path, 'r') as f:
    for _ in range(header):
        f.readline()

    for _ in range(footer):
        buffer.append(f.readline())

    for line in f:
        buffer.append(line)
        line = buffer.pop(0)

        # do stuff to line
        print(line)

跳过页眉行很简单我在跳过页脚行时遇到了问题,因为:

  • 我不想以任何方式手动更改文件
  • 我不想计算文件中的行数
  • 我不想将整个文件存储在列表中(即 readlines())^

^ 注意:如果你不介意将整个文件存储在内存中,你可以使用这个:

path = r'path\to\file.csv'
header = 2
footer = 2

with open(path, 'r') as f:
    for line in f.readlines()[header:-footer if footer else None]:
        # do stuff to line
        print(line)
于 2017-01-05T10:05:58.040 回答