Python脚本优化需求:完善ROI统计计算与CSV格式输出
问题描述
需求背景
- 存在多层嵌套文件夹结构,需从每个底层文件夹内的
.txt文件中,提取以cope1、cope2、cope3、cope4、cope5开头行的第6列数据。
已完成工作
已编写Python脚本实现数据提取与均值计算,当前输出结果如下:
{'ffa': {'cope1': 0.6525, 'cope2': 0.4146, 'cope3': 0.5896, 'cope4': 0.1521, 'cope5': 0.5317}, 'lingual': {'cope1': -0.08865060000000001, 'cope2': -0.150985, 'cope3': -0.162005, 'cope4': -0.130845, 'cope5': -0.126411}, 'ppa': {'cope1': 0.74836, 'cope2': 0.9444, 'cope3': 0.300482, 'cope4': 1.12435, 'cope5': 0.8332200000000001}}
待完善功能
- 统计参与者数量;
- 为每个ROI(ffa、lingual_gyrus、ppa)及刺激类别计算标准差与样本数;
- 将cope类型映射为对应刺激类别:
cope1→Bottle、cope2→Chair、cope3→Face、cope4→House、cope5→Shoe; - 以CSV格式(含表头)输出均值、标准差、样本数。
现有代码
import os import csv import pprint import statistics def main(): values = {} ffaResults = {} lingualResults = {} ppaResults = {} dir = os.path.join("pin-assessment1-master", "roi_data") subdirs = os.listdir(dir) for subdir in subdirs: subdirpath = os.path.join(dir, subdir) subsubdirs = os.listdir(subdirpath) for subsubdir in subsubdirs: if subsubdir == "ffa": dirpath = os.path.join(subdirpath, subsubdir) files = os.listdir(dirpath) for filename in files: path = os.path.join(dirpath, filename) with open(path, "r") as f: content = csv.reader(f, delimiter=" ") for row in content: if "cope" in row[1]: name = row[1].split("/")[1] if not name in values: ffaResults[name] = [float(row[6])] else: ffaResults[name].append(float(row[6])) if subsubdir == "lingual_gyrus": dirpath = os.path.join(subdirpath, subsubdir) files = os.listdir(dirpath) for filename in files: path = os.path.join(dirpath, filename) with open(path, "r") as f: content = csv.reader(f, delimiter=" ") for row in content: if "cope" in row[1]: name = row[1].split("/")[1] if not name in lingualResults: lingualResults[name] = [float(row[6])] else: lingualResults[name].append(float(row[6])) if subsubdir == "ppa": dirpath = os.path.join(subdirpath, subsubdir) files = os.listdir(dirpath) for filename in files: path = os.path.join(dirpath, filename) with open(path, "r") as f: content = csv.reader(f, delimiter=" ") for row in content: if "cope" in row[1]: name = row[1].split("/")[1] if not name in ppaResults: ppaResults[name] = [float(row[6])] else: ppaResults[name].append(float(row[6])) res = {"ffa": {}, "lingual": {}, "ppa": {}} for k in ffaResults: res["ffa"][k] = statistics.mean(ffaResults[k]) for k in lingualResults: res["lingual"][k] = statistics.mean(lingualResults[k]) for k in ppaResults: res["ppa"][k] = statistics.mean(ppaResults[k]) pprint.pprint(res) if __name__ == "__main__": main()
优化后的代码
import os import csv import statistics # 定义cope到刺激类别的映射 COPE_MAPPING = { 'cope1': 'Bottle', 'cope2': 'Chair', 'cope3': 'Face', 'cope4': 'House', 'cope5': 'Shoe' } def main(): # 统一存储所有ROI的数据,简化重复逻辑 roi_results = { 'ffa': {}, 'lingual_gyrus': {}, 'ppa': {} } # 统计参与者数量(假设每个子文件夹对应一位参与者) root_dir = os.path.join("pin-assessment1-master", "roi_data") participant_dirs = os.listdir(root_dir) participant_count = len(participant_dirs) # 遍历每个参与者文件夹 for subdir in participant_dirs: subdir_path = os.path.join(root_dir, subdir) # 遍历当前参与者下的所有ROI文件夹 for roi_name in roi_results.keys(): roi_dir = os.path.join(subdir_path, roi_name) if not os.path.exists(roi_dir): continue # 读取ROI下的所有文件 for filename in os.listdir(roi_dir): file_path = os.path.join(roi_dir, filename) with open(file_path, "r") as f: content = csv.reader(f, delimiter=" ") for row in content: if not row: continue # 筛选目标cope行 if row[1] and 'cope' in row[1]: cope_name = row[1].split("/")[1] if cope_name not in COPE_MAPPING: continue # 提取第6列数据并存储 value = float(row[6]) if cope_name not in roi_results[roi_name]: roi_results[roi_name][cope_name] = [] roi_results[roi_name][cope_name].append(value) # 准备CSV输出内容 csv_rows = [['ROI名称', '刺激类别', '均值', '标准差', '样本数']] # 计算统计指标并整理行数据 for roi_name, cope_data in roi_results.items(): for cope_name, values in cope_data.items(): stimulus = COPE_MAPPING[cope_name] mean_val = statistics.mean(values) # 样本数为1时标准差设为0 std_val = statistics.stdev(values) if len(values) > 1 else 0.0 sample_count = len(values) csv_rows.append([roi_name, stimulus, round(mean_val, 6), round(std_val, 6), sample_count]) # 输出参与者数量 print(f"参与者数量: {participant_count}") # 写入CSV文件 with open('roi_statistics.csv', 'w', newline='', encoding='utf-8') as csvfile: writer = csv.writer(csvfile) writer.writerows(csv_rows) print("统计结果已保存到roi_statistics.csv") if __name__ == "__main__": main()
关键实现说明
- 参与者数量统计:直接统计
roi_data目录下的子文件夹数量,默认每个子文件夹对应一位参与者; - 统计指标计算:对每个cope对应的数值列表,使用
statistics.mean()计算均值,statistics.stdev()计算样本标准差,列表长度即为样本数; - 类型映射:通过字典
COPE_MAPPING完成cope到刺激类别的转换; - CSV输出:构建包含表头的二维数据结构,使用
csv.writer写入文件,确保格式规范。
内容的提问来源于stack exchange,提问作者user20803234
相关产品推荐
相关产品推荐

