打开并读取以空格分隔的txt文件

时间:2019-02-03 20:49:22

标签: python csv

我有一个用空格分隔的txt文件,如下所示:

2004          Temperature for KATHMANDU AIRPORT       
        Tmax  Tmin
     1  18.8   2.4 
     2  19.0   1.1 
     3  18.3   1.7 
     4  18.3   1.0 
     5  17.8   1.3 

我想分别计算Tmax和Tmin的平均值。但是,我很难读取txt文件。我尝试过this link like

import re
list_b = []
list_d = []

with open('TA103019.95.txt', 'r') as f:
    for line in f:
        list_line = re.findall(r"[\d.\d+']+", line)
        list_b.append(float(list_line[1])) #appends second column
        list_d.append(float(list_line[3])) #appends fourth column

print list_b
print list_d

但是,这给了我错误:  IndexError: list index out of range 怎么了?

6 个答案:

答案 0 :(得分:2)

一种简单的解决方法是使用split()函数。 当然,您需要删除前两行:

['1', '18.8', '2.4']
['2', '19.0', '1.1']
['3', '18.3', '1.7']
['4', '18.3', '1.0']
['5', '17.8', '1.3']

您得到:

None

引用文档:

  

如果未指定 sep 或为{{1}},则将应用不同的拆分算法:连续空格的运行被视为单个分隔符,并且结果将不包含空字符串字符串的开头或结尾是空格的开始或结尾。

答案 1 :(得分:1)

here所述,re.findall列出了正则表达式的所有匹配项。您定义的表达式与文件中的任何内容都不匹配,因此您得到一个空数组,从而在尝试访问list_line[1]时导致错误。

  • 您要基于该文件匹配的表达式为r"\d+\.\d+",匹配任何十进制数字,其小数点前应至少有一位,该小数点后应至少一位。
  • 即使此表达式在前两行中都不匹配,所以您将需要检查空数组
  • 结果不知道任何列,只是模式的匹配,并且每个数据行都有两个匹配-您将要个性化01

所以:     汇入     list_b = []     list_d = []

with open('TA103019.95.txt', 'r') as f:
    for line in f:
        list_line = re.findall(r'\d+\.\d+', line)
        if len(list_line) == 2 :
            list_b.append(float(list_line[0])) #appends second column
            list_d.append(float(list_line[1])) #appends fourth column

print list_b
print list_d

答案 2 :(得分:1)

import re
list_b = []
list_d = []

with open('TA103019.95.txt', 'r') as f:
    for line in f:
        # regex is corrected to match the decimal values only
        list_line = re.findall(r"\d+\.\d+", line) 

        # error condition handled where the values are not found 
        if len(list_line) < 2: 
            continue

        # indexes are corrected below
        list_b.append(float(list_line[0])) #appends second column
        list_d.append(float(list_line[1])) #appends fourth column

print list_b
print list_d

我在代码本身中添加了我的答案和一些注释。

您之所以得到Index out of range error,是因为list_line仅具有单个元素(即文件的第一行中为2004),并且您试图访问list_line的第一个索引和第三个索引。

答案 3 :(得分:1)

完整解决方案

def readit(file_name,start_line = 2): # start_line - where your data starts (2 line mean 3rd line, because we start from 0th line) 
    with open(file_name,'r') as f:
        data = f.read().split('\n')
    data = [i.split(' ') for i in data[start_line:]]
    for i in range(len(data)):
        row = [(sub) for sub in data[i] if len(sub)!=0]
        yield int(row[0]),float(row[1]),float(row[2])


iterator = readit('TA103019.95.txt')


index, tmax, tmin = zip(*iterator)


mean_Tmax = sum(tmax)/len(tmax)
mean_Tmin = sum(tmin)/len(tmin)
print('Mean Tmax: ',mean_Tmax)
print('Mean Tmnin: ',mean_Tmin)

>>> ('Mean Tmax: ', 18.439999999999998)
>>> ('Mean Tmnin: ', 1.5)

感谢 Dan D。提供更优雅的解决方案

答案 4 :(得分:0)

简化您的生活,避免再次遇到这个问题。

也许您错误地阅读了标题行?如果文件的格式是固定的,我通常在开始循环之前先用读取的行来“烧写”标题行,例如:

with open(file_name, 'r') as f:
    f.readline()  # burn the header row
    for line in f:
        tokens = line.strip().split(' ')   # tokenize the row based on spaces

然后您将获得一个令牌列表,这些令牌将是您需要转换为int或float或任何东西然后从那里去的字符串!

输入几个打印语句以查看您要提取的内容...

答案 5 :(得分:0)

您的文件是否可能用制表符分隔?

对于制表符分隔:

with open('TA103019.95.txt', 'r') as f:
    for idx, line in enumerate(f):
        if idx > 1:                    
            cols = line.split('\t'): #for space delimited change '\t' to ' '
            tmax = float(col[1])
            tmin = float(col[2])
            #calc mean

            mean = (tmax + tmin) / 2
            #not sure what you want to do with the result