首页 > 解决方案 > 使用 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  

标签: pythonpandascsv

解决方案


不要附加数据框。这是一个非常缓慢的操作。理想情况下,我会这样做两遍:遍历文件一次以计算行数,然后倒回文件,创建适当大小的数据框,并通过直接索引将其填充到第二遍中。

作为微优化,请注意你做line.split()了很多次 - 它应该被缓存。


推荐阅读