处理从文本文件读取表格时的空白空间 Python

0 投票
3 回答
3930 浏览
提问于 2025-05-01 17:52

我需要解析一个文件,具体链接在下面这个地址:http://bit.ly/1x6yzoX

我写了一个方法来解析这个文件,但我无法读取最新年份(2014年)中不完整的数据,因为文本文件的表格里有空白的地方。现在我只能跳过那些我无法读取的行。

请帮我想想怎么解决这个问题?

LINES_TO_IGNORE = 7
import collections
import csv

def parse_file(data_file):
    result_dict = collections.OrderedDict()
    if not data_file:
        return result_dict

    with open(data_file) as f:
        reader = csv.reader(f, delimiter="\t")
        data = islice(reader, LINES_TO_IGNORE, None, None)
        if not data:
            return result_dict
        # Get file headers
        headers = data.next()
        headers = headers[0].split()
        keys = headers[1:]

        for row in data:
            values = row[0].split()
            if len(headers) == len(values):
                year = parse_to_int(values[0])
                data_list = [parse_to_float(x) for x in values[1:]]
                # Each line becomes a dict (column_header->value)
                data_dict = collections.OrderedDict(zip(keys, data_list))
            else:
                print "Skipping"
            # result_dict is dict of dict (year->data_dict)
            result_dict[year] = data_dict
    return result_dict
暂无标签

3 个回答

0

在编程中,有时候我们会遇到一些问题,可能是因为代码写得不够清晰,或者是我们对某些概念理解得不够透彻。比如说,某些函数的用法可能会让人感到困惑,尤其是当我们刚开始学习编程的时候。

在这种情况下,查看其他人的问题和答案是一个很好的学习方式。StackOverflow就是一个这样的地方,很多程序员会在这里提问,分享他们的经验和解决方案。

通过阅读这些内容,我们可以更好地理解编程中的一些常见问题和解决方法,这对我们提高编程技能非常有帮助。

def parse_file(data_file):
    result_dict = collections.OrderedDict()
    if not data_file:
        return result_dict

    with  open(data_file) as f:
        counter = 0
        headers = []
        for line in f.readlines():
            line = line.strip()
            counter += 1
            if counter == 1:
                headers = re.findall('\w+',line)
                keys = headers
            else:
                values =  re.findall('([\d\-\.]+|(?:\s){3,4})(?:(?:\s){3,4})?',line)
                year = parse_to_int(values[0])

                if len(headers) != len(values):
                    diff_list = ['NaN' for i in range(len(headers) - len(values))]
                    values.extend(diff_list)
                data_list = [parse_to_float(x) for x in values[1:]]
                data_dict = collections.OrderedDict(zip(keys, data_list))
                result_dict[year] = data_dict

    return result_dict
1

你可以很简单地用 Pandas 来实现:

import pandas as pd
data = pd.read_fwf('UK.txt', skiprows=7, delimiter=' ')

print data[-3:] 可以打印出最后几行数据:

    Year    JAN    FEB    MAR    APR    MAY    JUN    JUL    AUG    SEP    OCT  \
102  2012    1.8    1.2    3.4    2.5    6.0    8.8...
103  2013    1.0   -0.1   -0.7    2.2    5.2    8.6...
104  2014    2.1    2.5    2.9    5.3    7.3    9.9...

     NOV    DEC     WIN    SPR    SUM    AUT   ANN  Unnamed: 3  Unnamed: 4  \
102  2.8    1.1    1.73   4.00  10.19   5.23  5.21         NaN         NaN
103  2.4    2.8    0.68   2.26  10.66   6.56  5.21         NaN         NaN
104                       2.48   5.17  10.46   NaN         NaN         NaN

     Unnamed: 5  Unnamed: 6  Unnamed: 7
102         NaN         NaN         NaN
103         NaN         NaN         NaN
104         NaN         NaN         NaN

我觉得这还不是完全正确,但已经很接近了……希望你能把它完善好。如果使用Pandas,就不需要手动写那么多代码。

0

你可以使用 genfromtxt 这个函数,它来自 numpy 库。

import numpy as np
data = np.genfromtxt('UK.txt',skiprows=8,delimiter=(4,7,7,7,7,7,7,7,7,7,7,7,7,8,7,7,7,8))

这个函数会自动填补缺失的值,但你还是需要找到方法来确定每一列的大小和需要跳过的行数。

下面是如何从表头获取列的大小的方法:

import re
header="Year    JAN    FEB    MAR    APR    MAY    JUN    JUL    AUG    SEP    OCT    NOV    DEC     WIN    SPR    SUM    AUT     ANN"
cols=re.findall("\s*[^\s]+",header)
delimiter=tuple([len(c) for c in cols])

撰写回答