如何在Python中并发写入两个CSV?SDR数据存储问题求助
解决两台SDR设备独立保存多轮IQ数据到CSV的问题
我来帮你搞定这个问题,咱们先梳理下原来代码的几个核心问题,再一步步修改:
问题根源
- 文件名无设备区分:两台设备用同一个时间戳命名文件,互相覆盖,最后只能保留一台的数据
- 文件写入模式错误:用
w(清空写入)模式,每次扫描都会覆盖之前的内容,所以只能留最后一次数据 - 循环次数不符合需求:你要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),跳过保存")
关键改动说明
- 设备唯一标识:给每个SDR设备加了自定义ID(比如
sdr_device_1),通过starmap传递给扫描方法,确保文件名能区分不同设备 - 独立文件名设计:文件名包含
设备ID_扫描轮次_时间戳,彻底避免不同设备、不同轮次的数据互相覆盖 - 修正扫描次数:把循环改成
range(5),正好执行5次扫描 - 可读性优化:变量名更规范,添加了保存/跳过的提示日志,方便调试
可选方案:单个设备一个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
相关产品推荐
相关产品推荐

