python - 使用 Python 解析大型文本文件
问题描述
我必须将大 txt 文件的信息放入 pandas 数据框中。文本文件的格式如下(我无法以任何方式更改它):
o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o
Z_0 S_1 C_1
foo bar
foo_1 foo_2 foo_3 foo_4
0.5 1.2 3.5 2.4
X[m] Y[m] Z[m] alfa[-] beta[-]
-2.17142783E-04 3.12000068E-03 3.20351664E-01 3.20366857E+01 3.20366857E+01
-7.18630964E-04 2.99634764E-03 3.20343560E-01 3.20357573E+01 3.20357573E+01
-2.85056979E-03 -4.51947006E-03 3.20079900E-01 3.20111805E+01 3.20111805E+01
o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o
Z_0 S_2 C_1
foo bar
foo_1 foo_2 foo_3 foo_4
0.5 1.2 3.5 2.4
X[m] Y[m] Z[m] alfa[-] beta[-]
-2.17142783E-04 3.12000068E-03 3.20351664E-01 3.20366857E+01 3.20366857E+01
-7.18630964E-04 2.99634764E-03 3.20343560E-01 3.20357573E+01 3.20357573E+01
-2.85056979E-03 -4.51947006E-03 3.20079900E-01 3.20111805E+01 3.20111805E+01
o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o--o
Z_1 S_3 C_1
foo bar
foo_1 foo_2 foo_3 foo_4
0.5 1.2 3.5 2.4
X[m] Y[m] Z[m] alfa[-] beta[-]
-2.17142783E-04 3.12000068E-03 3.20351664E-01 3.20366857E+01 3.20366857E+01
-7.18630964E-04 2.99634764E-03 3.20343560E-01 3.20357573E+01 3.20357573E+01
-2.85056979E-03 -4.51947006E-03 3.20079900E-01 3.20111805E+01 3.20111805E+01
原始文件有超过 65K 行。
我想创建一个包含该文件信息的唯一数据框,包括分隔符后第一行中包含的数据框。我写了一个工作代码:
import os
import pandas as pd
my_path = r"C:\Users\212744206\Desktop\COSO"
my_file= os.path.join(my_path ,'my_file.dat')
istart = False
with open(my_file) as fp:
for i, line in enumerate(fp):
if (line[0] != 'o'):
if line.split()[0][0] == 'Z':
iZ = int((line.split()[0]).split('_')[1])
iS = int((line.split()[1]).split('_')[1])
iC = int((line.split()[2]).split('_')[1])
elif (line.split()[0] == 'X[m]') or (len(line.split()) == 2) or (len(line.split()) == 4):
continue
else:
dfline = pd.DataFrame(line.split())
dfline = dfline.transpose()
dfline.insert(0, column='C' , value=iC)
dfline.insert(0, column='S' , value=iS)
dfline.insert(0, column='Z' , value=iZ)
if istart == False:
df_zone = dfline.copy()
istart = True
else:
df_zone = df_zone.append(dfline, ignore_index=True, sort=False)
print(df_zone)
...但是对于我的应用程序来说它非常慢(最后的打印显然是出于调试原因,我不会将它与大文件一起使用)。如何以更“pythonic”和有效的方式编写它?接受所有建议!谢谢
编辑:不幸的是,我的“有用”数据可以有 3、4、5 或任何数量的行......此外,我需要解析行“Z_0 S_1 C_1”,因为我需要这样的输出:
Z S C 0 1 2 3 4
0 0 1 1 -2.17142783E-04 3.12000068E-03 3.20351664E-01 3.20366857E+01 3.20366857E+01
1 0 1 1 -7.18630964E-04 2.99634764E-03 3.20343560E-01 3.20357573E+01 3.20357573E+01
2 0 1 1 -2.85056979E-03 -4.51947006E-03 3.20079900E-01 3.20111805E+01 3.20111805E+01
3 0 2 1 -2.17142783E-04 3.12000068E-03 3.20351664E-01 3.20366857E+01 3.20366857E+01
4 0 2 1 -7.18630964E-04 2.99634764E-03 3.20343560E-01 3.20357573E+01 3.20357573E+01
5 0 2 1 -2.85056979E-03 -4.51947006E-03 3.20079900E-01 3.20111805E+01 3.20111805E+01
6 1 3 1 -2.17142783E-04 3.12000068E-03 3.20351664E-01 3.20366857E+01 3.20366857E+01
7 1 3 1 -7.18630964E-04 2.99634764E-03 3.20343560E-01 3.20357573E+01 3.20357573E+01
8 1 3 1 -2.85056979E-03 -4.51947006E-03 3.20079900E-01 3.20111805E+01 3.20111805E+01
解决方案
不要附加数据框。这是一个非常缓慢的操作。理想情况下,我会这样做两遍:遍历文件一次以计算行数,然后倒回文件,创建适当大小的数据框,并通过直接索引将其填充到第二遍中。
作为微优化,请注意你做line.split()
了很多次 - 它应该被缓存。
推荐阅读
- android - 实时计算记录并返回总记录数,然后在小部件中将其显示为文本
- javascript - 使用 javascript 操作 json
- mpi - MPI 术语中的 ScaLAPACK 子例程是否“阻塞”?
- mpdf - :before 和 :after CSS 属性在 MPDF 中不起作用
- java - 如何使 ExampleMatcher 与属性不匹配?
- ios - 在 iOS 13 上拖动时,UICollectionView 单元格捕捉到原始位置
- google-cloud-platform - Dataflow REST API 的“projects.locations.templates.create”和“projects.locations.templates.launch”有什么区别?
- c# - 在 Visual Studio Development 中上传文件时有效,但在网站发布时无效
- c# - C# Azure:如何从 Microsoft.Azure.ServiceBus.Message 读取正文?
- django - mysqlclient在mac os上的python3中安装