.78D文件转换为.asc文件再转换为.csv文件并分列

SR785频谱仪由于保存数据时的格式问题,所以处理数据时需要进行转换,通过下面的程序可以缩短处理数据的时间。

代码如下:

import os
import subprocess
import csv
import numpy as np
import matplotlib.pyplot as plt


def process_asc_file(asc_file_path, folder_path):
    # 生成对应的 CSV 文件路径
    csv_file_name = os.path.splitext(os.path.basename(asc_file_path))[0] + '.csv'
    csv_file_path = os.path.join(folder_path, csv_file_name)
    split_csv_file_name = os.path.splitext(os.path.basename(asc_file_path))[0] + '_split.csv'
    split_csv_file_path = os.path.join(folder_path, split_csv_file_name)

    print(f"尝试将 {asc_file_path} 转换为 {csv_file_path}")
    try:
        # 步骤 1: 按行读取 ASC 文件并写入 CSV 文件
        with open(asc_file_path, 'r', encoding='utf-8') as asc_file, open(csv_file_path, 'w', newline='',
                                                                          encoding='utf-8') as csv_file:
            csv_writer = csv.writer(csv_file)
            for line in asc_file:
                csv_writer.writerow([line.strip()])
        print(f"文件 {os.path.basename(asc_file_path)} 已成功转换为 {os.path.basename(csv_file_path)}")
    except FileNotFoundError:
        print(f"错误:未找到文件 {asc_file_path} 或无法创建 {csv_file_path}")
    except PermissionError:
        print(f"错误:没有权限访问 {asc_file_path} 或写入 {csv_file_path}")
    except Exception as e:
        print(f"将 {os.path.basename(asc_file_path)} 转换为 {os.path.basename(csv_file_path)} 时出现未知错误: {e}")
        return

    # 步骤 2: 提取数据部分(从 X[Hz] 行之后的两列数值)
    data = []
    in_data_section = False
    try:
        with open(asc_file_path, 'r', encoding='utf-8') as asc_file:
            for line in asc_file:
                if line.strip().startswith('    X[Hz]'):
                    in_data_section = True
                    continue
                if in_data_section:
                    parts = line.strip().split()
                    if len(parts) == 2:
                        try:
                            x = float(parts[0])
                            y = float(parts[1])
                            data.append([x, y])
                        except ValueError:
                            continue
    except Exception as e:
        print(f"从 {os.path.basename(asc_file_path)} 提取数据时出现错误: {e}")

    # 步骤 3: 若提取到有效数据,计算原数据第二列的最大值
    if data:
        data_array = np.array(data)
        max_value = np.max(data_array[:, 1])
        print(f"文件 {os.path.basename(asc_file_path)} 原数据第二列的最大值是: {max_value}")
    else:
        print(f"文件 {os.path.basename(asc_file_path)} 未提取到有效数据,请检查文件格式。")

    print(f"尝试处理 {csv_file_path} 并保存为 {split_csv_file_path}")
    try:
        # 步骤 4: 将 CSV 文件中第 11 行到第 812 行根据空格拆分成两列并保存到第 6、7 列
        with open(csv_file_path, 'r', encoding='utf-8') as infile, \
                open(split_csv_file_path, 'w', newline='', encoding='utf-8') as outfile:
            reader = csv.reader(infile)
            writer = csv.writer(outfile)

            for i, row in enumerate(reader, start=1):
                new_row = row.copy()
                if 11 <= i <= 812:
                    line_content = row[0]
                    parts = line_content.split()
                    if len(parts) == 2:
                        # 确保新行有足够的列数
                        while len(new_row) < 7:
                            new_row.append('')
                        new_row[5] = parts[0]
                        new_row[6] = parts[1]
                writer.writerow(new_row)
        print(f"文件 {os.path.basename(csv_file_path)} 已成功处理并保存为 {os.path.basename(split_csv_file_path)}")
    except FileNotFoundError:
        print(f"错误:未找到文件 {csv_file_path} 或无法创建 {split_csv_file_path}")
    except PermissionError:
        print(f"错误:没有权限访问 {csv_file_path} 或写入 {split_csv_file_path}")
    except Exception as e:
        print(
            f"处理 {os.path.basename(csv_file_path)} 并保存为 {os.path.basename(split_csv_file_path)} 时出现未知错误: {e}")

    # 步骤 5: 在 _split.csv 文件中寻找第 7 列的 3 个最大值及对应第 6 列的平均值
    column_6_data = []
    column_7_data = []
    try:
        with open(split_csv_file_path, 'r', encoding='utf-8') as csvfile:
            reader = csv.reader(csvfile)
            for i, row in enumerate(reader, start=1):
                if 11 <= i <= 812 and len(row) >= 7:
                    try:
                        freq = float(row[5])
                        value = float(row[6])
                        column_6_data.append(freq)
                        column_7_data.append(value)
                    except ValueError:
                        continue
    except Exception as e:
        print(f"从 {os.path.basename(split_csv_file_path)} 读取数据时出现错误: {e}")

    if len(column_7_data) >= 3:
        sorted_indices = np.argsort(column_7_data)[::-1]
        selected_max_indices = []
        for index in sorted_indices:
            if not selected_max_indices:
                selected_max_indices.append(index)
            else:
                # 检查间隔是否至少为 50Hz
                is_valid = True
                for selected_index in selected_max_indices:
                    if abs(column_6_data[index] - column_6_data[selected_index]) < 50:
                        is_valid = False
                        break
                if is_valid:
                    selected_max_indices.append(index)
            if len(selected_max_indices) == 3:
                break

        if len(selected_max_indices) == 3:
            max_values = [column_7_data[i] for i in selected_max_indices]
            corresponding_freqs = [column_6_data[i] for i in selected_max_indices]
            avg_freq = np.mean(corresponding_freqs)
            print(f"文件 {os.path.basename(split_csv_file_path)} 第 7 列的 3 个最大值是: {max_values}")
            print(f"对应的第 6 列频率的平均值是: {avg_freq}")
        else:
            print(f"文件 {os.path.basename(split_csv_file_path)} 未找到满足间隔至少 50Hz 的 3 个最大值。")
    else:
        print(f"文件 {os.path.basename(split_csv_file_path)} 第 7 列数据不足,无法找到 3 个最大值。")

    # 步骤 6: 若提取到有效数据,根据第 6 列和第 7 列的数据画图
    if data:
        plot_data = []
        try:
            with open(split_csv_file_path, 'r', encoding='utf-8') as csvfile:
                reader = csv.reader(csvfile)
                for i, row in enumerate(reader, start=1):
                    if 11 <= i <= 812 and len(row) >= 7:
                        try:
                            x = float(row[5])
                            y = float(row[6])
                            plot_data.append([x, y])
                        except ValueError:
                            continue
        except Exception as e:
            print(f"从 {os.path.basename(split_csv_file_path)} 读取绘图数据时出现错误: {e}")

        if plot_data:
            plot_array = np.array(plot_data)
            plt.plot(plot_array[:, 0], plot_array[:, 1])
            plt.xlabel('Column 6 Data')
            plt.ylabel('Column 7 Data')
            plt.title(f'Plot for {os.path.basename(asc_file_path)}')
            plt.grid(True)
            plt.show()


# 定义要检索的文件夹路径
folder_path = r"C:\SRTRANS"
# 用于存储符合条件的文件名
file_list = []

# 检查指定的文件夹是否存在
if os.path.exists(folder_path):
    # 遍历文件夹及其子文件夹,找出所有 .78D 文件
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.78d'):
                file_list.append(file)

    print("找到的 .78D 文件列表:", file_list)
    print("找到的 .78D 文件个数:", len(file_list))

    # srtrans 可执行文件的完整路径
    srtrans_path = os.path.join(folder_path, "srtrans.exe")

    # 检查 srtrans 可执行文件是否存在
    if not os.path.exists(srtrans_path):
        print(f"srtrans 可执行文件 {srtrans_path} 不存在,请检查。")
    else:
        for file in file_list:
            try:
                # 构造完整的文件路径
                full_file_path = os.path.join(folder_path, file)
                # 构造转换命令
                command = [srtrans_path, '/Oasc', full_file_path]
                # 执行命令
                result = subprocess.run(command, capture_output=True, text=True, check=True)
                output = result.stdout
                # 修正判断条件
                if "Finished" in output:
                    print(f"文件 {file} 转换完成。")
                    asc_file_path = os.path.splitext(full_file_path)[0] + '.asc'
                    process_asc_file(asc_file_path, folder_path)
                else:
                    print(f"文件 {file} 转换可能出现问题,输出信息:{output}")
            except subprocess.CalledProcessError as e:
                print(f"处理文件 {file} 时出现错误,错误信息:{e.stderr}")
            except Exception as e:
                print(f"处理文件 {file} 时出现未知错误:{e}")
else:
    print(f"指定的文件夹 {folder_path} 不存在。")

print("运行结束")

编写过程中的注意事项:

1. 转换完成判断条件拼写错误

在判断 .78D 文件是否成功转换为 .asc 文件时,代码里用的判断条件是 if "Finshed" in output:,然而 srtrans 工具输出的完成信息里 “Finished” 拼写正确,所以原代码的判断条件始终为 False,程序会误判转换可能出现问题,进而不执行后续对 .asc 文件的处理操作。

# 原错误代码
if "Finshed" in output:
    print(f"文件 {file} 转换完成。")
    asc_file_path = os.path.splitext(full_file_path)[0] + '.asc'
    process_asc_file(asc_file_path, folder_path)
# 修正后的代码
if "Finished" in output:
    print(f"文件 {file} 转换完成。")
    asc_file_path = os.path.splitext(full_file_path)[0] + '.asc'
    process_asc_file(asc_file_path, folder_path)
  1. 条件判断:检查字符串 "Finished" 是否存在于变量 output 中。由于修正了拼写错误,只要 srtrans 工具输出的信息里包含 “Finished”,就表示 .78D 文件成功转换为 .asc 文件。
  2. 转换成功处理:若 "Finished" 存在于 output 中,程序会打印一条消息,表明文件 file 转换完成。
  3. 生成 .asc 文件路径:和原错误代码一样,使用 os.path.splitext 函数生成转换后的 .asc 文件路径 asc_file_path
  4. 处理 .asc 文件:调用 process_asc_file 函数对生成的 .asc 文件进行处理。

2. 异常处理不够细致

虽然原代码有异常处理逻辑,但不够细致,对于文件操作时可能出现的 FileNotFoundError 和 PermissionError 没有单独处理,这使得在出现这些错误时,难以精准定位问题。

# 原代码异常处理
try:
    with open(asc_file_path, 'r', encoding='utf-8') as asc_file, open(csv_file_path, 'w', newline='',
                                                                      encoding='utf-8') as csv_file:
        csv_writer = csv.writer(csv_file)
        for line in asc_file:
            csv_writer.writerow([line.strip()])
except Exception as e:
    print(f"将 {os.path.basename(asc_file_path)} 转换为 {os.path.basename(csv_file_path)} 时出现未知错误: {e}")
    return

# 修正后代码异常处理
try:
    with open(asc_file_path, 'r', encoding='utf-8') as asc_file, open(csv_file_path, 'w', newline='',
                                                                      encoding='utf-8') as csv_file:
        csv_writer = csv.writer(csv_file)
        for line in asc_file:
            csv_writer.writerow([line.strip()])
except FileNotFoundError:
    print(f"错误:未找到文件 {asc_file_path} 或无法创建 {csv_file_path}")
except PermissionError:
    print(f"错误:没有权限访问 {asc_file_path} 或写入 {csv_file_path}")
except Exception as e:
    print(f"将 {os.path.basename(asc_file_path)} 转换为 {os.path.basename(csv_file_path)} 时出现未知错误: {e}")
    return
  • try 块
    • 运用 with 语句同时打开两个文件,一个是以只读模式('r')打开的 asc_file_path 对应的 .asc 文件,另一个是以写入模式('w')打开的 csv_file_path 对应的 .csv 文件。
    • 借助 csv.writer 创建一个 CSV 写入器对象 csv_writer
    • 逐行读取 .asc 文件的内容,对每行内容去除首尾空白字符后,以列表形式写入 .csv 文件。
  • except 块
  • except FileNotFoundError:专门捕获文件未找到的异常。当尝试打开的 .asc 文件不存在或者无法创建 .csv 文件时,会触发该异常,接着打印一条包含文件路径的错误信息。
  • except PermissionError:专门捕获权限错误异常。当没有足够权限访问 .asc 文件或者写入 .csv 文件时,会触发该异常,然后打印一条包含文件路径的错误信息。
  • except Exception as e:捕获除了 FileNotFoundError 和 PermissionError 之外的其他异常,打印错误信息并执行 return 语句,终止后续操作。

3. 缺乏详细日志输出

原代码在文件操作过程中缺乏详细的日志输出,当出现问题时,难以知晓程序具体执行到哪一步,无法快速定位问题。修正后的代码添加了详细的日志输出,比如在尝试转换 .asc 为 .csv 文件以及处理 .csv 文件生成 _split.csv 文件时,都会输出相应的提示信息,方便排查问题。

# 修正后添加的日志输出
print(f"尝试将 {asc_file_path} 转换为 {csv_file_path}")
print(f"尝试处理 {csv_file_path} 并保存为 {split_csv_file_path}")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值