You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中并发写入两个CSV?SDR数据存储问题求助

解决两台SDR设备独立保存多轮IQ数据到CSV的问题

我来帮你搞定这个问题,咱们先梳理下原来代码的几个核心问题,再一步步修改:

问题根源

  1. 文件名无设备区分:两台设备用同一个时间戳命名文件,互相覆盖,最后只能保留一台的数据
  2. 文件写入模式错误:用w(清空写入)模式,每次扫描都会覆盖之前的内容,所以只能留最后一次数据
  3. 循环次数不符合需求:你要5次扫描,但代码里写的是range(0,1),只执行1次

修改后的完整代码

主代码部分

# 给每个SDR设备绑定唯一标识,方便区分文件
radios = [("sdr_device_1", sdr), ("sdr_device_2", sdr2)]
pool = ThreadPool(4)
s = Scan()
# 用starmap传递多参数(设备ID+设备实例)
pool.starmap(s.scan, radios)
pool.close()
pool.join()

Scan类部分

import csv
import math
import time
import numpy as np

class Scan:
    def scan(self, device_id, sdr_device):
        # 执行5次扫描,对应你的需求
        for scan_round in range(5):
            # 读取IQ样本数据
            samples = sdr_device.read_samples(256*1024)
            
            # 频域计算逻辑(和你原来的一致,只是变量名更规范)
            sp = np.fft.fft(samples)
            ps_real = sp.real
            ps_imag = sp.imag
            sq = np.power(ps_real, 2) + np.power(ps_imag, 2)
            sqrt_val = np.sqrt(sq)
            psd = sqrt_val / 1024
            max_psd = np.max(psd)
            log_dB = 10 * math.log10(max_psd)
            
            # 生成唯一文件名:设备ID + 轮次 + 时间戳
            time_tag = time.strftime("%m.%d.%y-%H%M", time.localtime())
            # 方案1:每次扫描生成独立文件(推荐,避免数据混在一起)
            filename = f"{device_id}_scan_{scan_round+1}_{time_tag}.csv"
            
            # 当幅值大于-1dB时保存数据
            if log_dB > -1:
                # 用'w'模式写入独立文件,避免覆盖
                with open(filename, 'w', newline='') as f:
                    writer = csv.writer(f, delimiter=',')
                    # 可选:添加表头,让CSV更易读
                    writer.writerow(["Real_Part", "Imaginary_Part"])
                    writer.writerows(zip(ps_real, ps_imag))
                print(f"✅ 设备[{device_id}]第{scan_round+1}次扫描数据已保存到:{filename}")
            else:
                print(f"⚠️ 设备[{device_id}]第{scan_round+1}次扫描幅值不足(-1dB),跳过保存")

关键改动说明

  1. 设备唯一标识:给每个SDR设备加了自定义ID(比如sdr_device_1),通过starmap传递给扫描方法,确保文件名能区分不同设备
  2. 独立文件名设计:文件名包含设备ID_扫描轮次_时间戳,彻底避免不同设备、不同轮次的数据互相覆盖
  3. 修正扫描次数:把循环改成range(5),正好执行5次扫描
  4. 可读性优化:变量名更规范,添加了保存/跳过的提示日志,方便调试

可选方案:单个设备一个CSV文件(追加所有轮次数据)

如果你希望每个设备只生成一个CSV,把5次扫描的数据都追加进去,可以修改文件名和写入模式:

import os  # 需额外导入os模块

class Scan:
    def scan(self, device_id, sdr_device):
        # 在循环外定义统一文件名
        time_tag = time.strftime("%m.%d.%y-%H%M", time.localtime())
        filename = f"{device_id}_all_scans_{time_tag}.csv"

        # 第一次写入时添加表头
        if not os.path.exists(filename):
            with open(filename, 'w', newline='') as f:
                writer = csv.writer(f)
                writer.writerow(["Scan_Round", "Real_Part", "Imaginary_Part"])

        # 执行5次扫描
        for scan_round in range(5):
            # ... 前面的读取、计算逻辑和之前一致 ...
            if log_dB > -1:
                with open(filename, 'a', newline='') as f:
                    writer = csv.writer(f)
                    # 每行加上扫描轮次,方便区分不同批次的数据
                    for real, imag in zip(ps_real, ps_imag):
                        writer.writerow([scan_round+1, real, imag])
                print(f"✅ 设备[{device_id}]第{scan_round+1}次扫描数据已追加到:{filename}")

这样每个设备会生成一个包含所有5次扫描数据的CSV,每行都标注了对应的扫描轮次。


内容的提问来源于stack exchange,提问作者Contact-us Behind The Sciences

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:08:45