使用Python读取.txt数据

3

我有一个像这样的.txt文件:

# 经纬度
x1 = 11.21  
x2 = 11.51

y1 = 27.84  
y2 = 10.08

time: 201510010000  
变量名: val1  
[1.1,1.2,1.3]  
变量名: va2    
[1.0,1.01,1.02]  

time: 201510010100  
变量名: val1  
[2.1,2.2,2.3]  
变量名: va2  
[2.01,2.02,2.03]

time: 2015020000  
变量名: val1  
[3.0,3.1,3.2]  
变量名: val2  
[3.01,3.02,3.03]

time: 2015020100  
变量名: val1  
[4.0,4.1,4.2]  
变量名: val2    
[401,4.02,4.03]

并且,我希望能够用Python读取它,像这样:

enter image description here

with open('text.txt','r',encoding='utf-8') as f:
    lines = f.readlines()
    for line in lines:
        print(line,)

这是我所做的,但我对下一步没有头绪。

我该如何达成它?


4
下一步是什么? - Sayse
我个人会将数据导出为 .csv 或 .asc 文件。 只是一堆格式解析。 - tgikal
数据结构很复杂,所以我担心将数据导出到 .csv 格式可能无法工作。 - user10025959
你有 a.txt 文件并打开了 text.txt 文件来读取?请问你是否能清楚地表达你的问题? - Ersel Er
感谢指出错误,我的本地文件夹中的文件名为text.txt。 - user10025959
4个回答

0

我建议您将.txt格式更改为.ini文件或.csv文件。无论如何,您都可以使用字典。

dict = {}
file = open("file.txt")
text = file.readline()
i=0
for i in range (text.lenght):
   if text[i][0:5]=="time":
      dict[text[i]] = []
      dict[text[i]].append(text[i+2])
      dict[text[i]].append(text[i+4])

那段代码可能适用于您的文件,但如果您更改格式,将更容易将数据存储在字典中。 希望我有所帮助。


感谢您的帮助。我有一些问题。1)第3行是否最好使用.readlines;2)第5行中“属性”长度的意思是什么,它会出现AttributeError:“列表”对象没有属性“长度”。 - user10025959

0
为了以所需格式获取数据,您可以将相关部分添加到字典中,然后将其转换为数据框:
import ast
import pandas as pd

with open('text.txt','r', encoding='utf-8') as f:
    lines = f.readlines()
    d = {"time":[],
         "val1":[],
         "val2":[]}

    for i, line in enumerate(lines):
        if line[:5] == "time:":
            time = line.strip().split()[-1]

            #Reading string representations of lists as lists
            v1 = ast.literal_eval(lines[i+2].strip())
            v2 = ast.literal_eval(lines[i+4].strip())

            #Counting number of vals per date
            n1 = len(v1)
            n2 = len(v2)

            #Padding values if any are missing
            if n1 > n2:
                v2 += [None] * n1-n2
            elif n2 > n1:
                v1 += [None] * n2-n1

            d["time"].extend([time] * max(n1,n2))
            d["val1"].extend(v1)
            d["val2"].extend(v2)

df = pd.DataFrame(d)

print(df)

            time  val1    val2
0   201510010000   1.1    1.00
1   201510010000   1.2    1.01
2   201510010000   1.3    1.02
3   201510010100   2.1    2.01
4   201510010100   2.2    2.02
5   201510010100   2.3    2.03
6     2015020000   3.0    3.01
7     2015020000   3.1    3.02
8     2015020000   3.2    3.03
9     2015020100   4.0  401.00
10    2015020100   4.1    4.02
11    2015020100   4.2    4.03

感谢您的帮助。代码非常漂亮和简单。谢谢。 - user10025959

0

我正在学习Python,这是我想出来的代码 :) 如果有人发现错误,请友善地指出。

time = ""
val1 = []
val2 = []
final_list = []
process_val1 = False
process_val2 = False
with open('read.txt','r',encoding='utf-8') as f:
    lines = f.readlines()
    for line in lines:
        try:
            line = line.strip()
            if val1 and val2 and time != '':
                for v1, v2 in zip(val1, val2):
                    final_list.append([time, v1, v2])
                val1 = []
                val2 = []
                time = ''
                continue
            if process_val1 == True:
                val1 = line.split('[')[1].split(']')[0].split(',')
                process_val1 = False
                continue
            if process_val2 == True:
                val2 = line.split('[')[1].split(']')[0].split(',')
                process_val2 = False
                continue
            if 'time:' in line:
                time = line.split(": ")[1]
                continue
            elif 'val1' in line:
                process_val1 = True
                continue
            elif 'val2' in line:
                process_val2 = True
                continue
            elif 'va2' in line:
                process_val2 = True
                continue
            else:
                continue
        except:
            #handle exception here
            pass
    if final_list:
        with open('write.txt', 'w') as w:
            for list in final_list:
                w.write(", ".join(list) + '\n')

感谢您的帮助。这个方法很棒,而且运作良好。再次感谢您。 - user10025959
我有一个问题。 "try和except函数"是必要的吗?因为当我删除"try和except函数"时,代码可以正常工作。 - user10025959
谢谢:)。在代码中,try和except块用于处理异常。它现在可能很好用,因为我尝试根据您提供的示例创建了一段代码。但是,如果数据格式发生变化,我不确定它会如何反应,因此添加了try-except块。 - javapyscript
好的,我明白了。再次感谢。 - user10025959

0

首先,根据您的描述,我假设“经纬度”下面的x1、x2、y1和y2对您没有任何意义。

假设您只需要图片中显示的数据,并且原始数据格式与示例相同(例如,只有两列数据,即val1和val2;每个时间戳始终有3个值的val1和val2;val2始终在val1之后),则以下解决方案应该可行:

import re

#define 4 patterns
p1=r'time:\s*(\d+)' # for time: 201510010000
p2=r'\[([\d\.]+),([\d\.]+),([\d\.]+)\]' # for [1.1,2.1,3.1]
v1p=u'变量名:\s*val1' # for val1
v2p=u'变量名:\s*val2' # for val2
inV1=False # the flag to show if next line is for val1
inV2=False # the flag to show if next line is for val1
time_column=''
csv_f=open('output.csv','w',encoding='utf-8') #open a csv file for writing
csv_f.write('time,val1,val2')

with open('text.txt','r',encoding='utf-8') as f:
    lines = f.readlines()
    for line in lines:
        m=re.match(p1,line)
        if m and time_column != m.groups()[0]:
            time_column = m.groups()[0]
            #reset the flags
            inV1=False
            inV2=False
            continue
        if re.match(v1p,line):
            inV1=True
            continue            
        if re.match(v2p,line):
            inV2=True
            continue            
        m=re.match(p2,line)
        if not m: continue
        if inV1:
            val1=m.groups()          
        if inV2: # we should ouput all the values for a timestamp since both val2 and val1 are ready now
            val2=m.groups()
            for i in range(0,3):
                l="{0},{1},{2}".format(time_column,val1[i],val2[i])
                csv_f.write("\n"+l)
    csv_f.close() #close the csv file

上述代码的作用是解析给定的文本,并将格式化输出写入名为“output.csv”的csv文件中,该文件与"text.txt"位于同一文件夹中。您可以直接使用MS Excel或任何其他电子表格编辑器或查看器打开它。
我在这里使用了正则表达式,因为它最灵活,您始终可以修改模式以满足您的需求,而不更改其余逻辑。此外,使用标志的优点是不会被文本中可能存在的重复行所困扰。
如果您有进一步的要求,请留言。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接