csv 如何拆分具有多个表的数据(.dat)文件?

xxls0lw8  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(247)

我正在处理一个.dat文件,其中包含几个给定数据表。
我已经看了几个解决方案,但我没有设法找到正确的和相关的答案来回答我的问题。
下面是其中一个文件的一个小示例:

13x8E                    (13x8E.dat)                                  12/21/14                       
                                                                                                              
                                                                                                              
         ====== PERFORMANCE DATA (versus advance ratio and MPH) ======                                        
                                                                                                              
         DEFINITIONS:                                                                                         
         J=V/nD (advance ratio)                                                                               
         Ct=T/(rho * n**2 * D**4) (thrust coef.)                                                              
         Cp=P/(rho * n**3 * D**5) (power coef.)                                                               
         Pe=Ct*J/Cp (efficiency)                                                                              
         V  (model speed in MPH)                                                                              
                                                                                                              
                                                                                                              
         PROP RPM =       1000                                                                                
                                                                                                              
         V          J           Pe         Ct          Cp          PWR         Torque      Thrust             
       (mph)     (Adv Ratio)                                       (Hp)        (In-Lbf)     (Lbf)             
         0.0        0.00      0.0000      0.1003      0.0426       0.001       0.079       0.090              
         0.4        0.03      0.0660      0.1001      0.0434       0.001       0.080       0.090              
         0.7        0.06      0.1292      0.0997      0.0441       0.001       0.081       0.089              
        ...
        ...
         9.8        0.80      0.5192      0.0056      0.0087       0.000       0.016       0.005              
        10.2        0.83     -0.0017      0.0000      0.0045       0.000       0.008       0.000              
                                                                                                              
                                                                                                              
                                                                                                              
         PROP RPM =       2000                                                                                
                                                                                                              
         V          J           Pe         Ct          Cp          PWR         Torque      Thrust             
       (mph)     (Adv Ratio)                                       (Hp)        (In-Lbf)     (Lbf)             
         0.0        0.00      0.0000      0.1004      0.0427       0.010       0.315       0.360              
         0.7        0.03      0.0659      0.1001      0.0434       0.010       0.321       0.359

我设法做到这一点,通过手动分割的基础上PROP RPM值,然后读取阵列(二维阵列),最后堆叠所有的阵列,以创建一个三维阵列的一个文件。
有没有更好的方法来执行此任务?
我打算将这些数据用于我的研究,并且有许多相同格式的文件。因此,对整个文件执行手动输入对我来说似乎是个坏主意。
这个文件也包含一些NaN数据。最初。我想插入数据来填充这个NaN值。但是,跳过数据可能更容易解决。
以下是完整的档案:Sample File

h9vpoimq

h9vpoimq1#

我以前处理过类似的文件--NASA的气候数据--当时我在帮助一个朋友写论文。
这些文件的扩展名是PRT。我不知道它们是不是一样的,但我之所以提出这个问题,是因为我的朋友一开始就不应该收到这种文件。当一些员工了解到我的朋友在处理什么时,确实有一个手碰到额头的时刻;工作人员随后提供了不需要任何特殊处理的netCDF文件。
但是,如果这就是你要处理的全部内容,我们可以用一种相当直接的方式编写一个像样的解析器,我们将把文件作为文本读取,并逐行处理它。
我看到前13行中的一些前同步码数据并不重要,因此我们将跳过这13行,在一个小循环中丢弃这些数据。
从这里开始循环遍历每一行:

  • 将跳过空白行。
  • 如果我们遇到一行带有“PROPRPM”的代码,这表示一个新表的开始,我们将解析该行并提取RPM值,并将其称为表的ID。

一个表的开始可能也意味着前一个表的最终结束,因此我们将使用最后一个表的ID保存任何先前解析的行。
然后,我们将跳过接下来的三行,并重置行数据列表(丢弃前面的行),为后面的行让路。

  • 接下来的几行应该都是行数据,我们将根据列宽解析它们。Python的float()函数可以处理带有填充空格的数字,比如' 1.23 'NaN,所以一旦我们定义了列宽,就没有额外的工作了。
  • 最后,我们将到达文件的末尾,需要保存最后一个表的行。

如果您不是很熟悉continue语句,我使用它来简化循环,当不再处理当前行时,使循环从下一行开始;向我们真正关心的行移动。

import csv

def save_table(table_id, rows):
    with open(f"rpm_{table_id:05}.csv", "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=rows[0])
        writer.writeheader()
        writer.writerows(rows)

f_dat = open("input.dat")

# discard preamble; skip to data
for i in range(13):
    next(f_dat)

# initialize state vars
table_id = 0
rows = []

for line in f_dat:
    # don't strip line up front, to make reading and
    # setting the column widths easier

    if line.strip() == "":
        continue

    if line.strip().startswith("PROP RPM"):
        if rows != []:
            save_table(table_id, rows)

        table_id = int(line.strip().rsplit(" ", 1)[1])
        rows = []

        for i in range(3):
            next(f_dat)  # skip blank line and two "header" lines

        continue

    # At a row/data line now...
    row = {
        "V": float(line[0:12]),
        "J": float(line[12:24]),
        "Pe": float(line[24:36]),
        "Ct": float(line[36:48]),
        "Cp": float(line[48:60]),
        "PWR": float(line[60:72]),
        "Torque": float(line[72:84]),
        "Thrust": float(line[84:96]),
    }

    rows.append(row)

# save last table at end of file
if rows != []:
    save_table(table_id, rows)

将所有表格拆分为单独的CSV文件后,我相信您可以将它们合并到3D数组中。

相关问题