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

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}}

待完善功能

  1. 统计参与者数量;
  2. 为每个ROI(ffa、lingual_gyrus、ppa)及刺激类别计算标准差与样本数;
  3. 将cope类型映射为对应刺激类别:cope1→Bottle、cope2→Chair、cope3→Face、cope4→House、cope5→Shoe;
  4. 以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()

关键实现说明

  1. 参与者数量统计:直接统计roi_data目录下的子文件夹数量,默认每个子文件夹对应一位参与者;
  2. 统计指标计算:对每个cope对应的数值列表,使用statistics.mean()计算均值,statistics.stdev()计算样本标准差,列表长度即为样本数;
  3. 类型映射:通过字典COPE_MAPPING完成cope到刺激类别的转换;
  4. CSV输出:构建包含表头的二维数据结构,使用csv.writer写入文件,确保格式规范。

内容的提问来源于stack exchange,提问作者user20803234

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:50:22