python_for_asl/Code/5-ANOVA-SciPy.py
2025-08-06 02:04:35 +08:00

150 lines
5.3 KiB
Python

import numpy as np
import openpyxl
import csv
import os.path
from scipy.stats import f_oneway
def read_value(patient_dir, atlas, data_type):
folder_name = os.path.basename(patient_dir)
csv_file_path = os.path.join(patient_dir, f"{data_type}_{atlas}_result", "result_atlas.csv")
result = [folder_name]
with open(csv_file_path, mode='r') as data_csv_file:
csv_reader = csv.DictReader(data_csv_file)
for row in csv_reader:
mean = float(row["meanValue"])
result.append(mean)
return result
def read_header(patient_dir, atlas, data_type):
header = ['编号']
csv_file_path = os.path.join(patient_dir, f"{data_type}_{atlas}_result", "result_atlas.csv")
with open(csv_file_path, mode='r') as data_csv_file:
csv_reader = csv.DictReader(data_csv_file)
for row in csv_reader:
region_name = row["Chinese Name"]
header.append(region_name)
return header
def generate_stats_row(name, region_size, function, patient_size, extra_parameter):
result = [name]
for i in range(region_size):
letter = openpyxl.utils.cell.get_column_letter(i + 2)
result.append(f'={function}({letter}2:{letter}{patient_size + 1}{extra_parameter})')
return result
def write_to_work_sheet(work_sheet, patient_list, atlas, data_type):
if len(patient_list) == 0:
return
header = read_header(patient_list[0], atlas, data_type)
work_sheet.append(header)
for patient_dir in patient_list:
print(data_type, patient_dir)
patient_data = read_value(patient_dir, atlas, data_type)
work_sheet.append(patient_data)
region_size = len(header) - 1
work_sheet.append([])
work_sheet.append([])
work_sheet.append(generate_stats_row('均值', region_size, 'AVERAGE', len(patient_list), ''))
work_sheet.append(generate_stats_row('标准差', region_size, 'STDEV', len(patient_list), ''))
work_sheet.append(generate_stats_row('最小值', region_size, 'MIN', len(patient_list), ''))
work_sheet.append(generate_stats_row('5%', region_size, 'PERCENTILE', len(patient_list), ',0.05'))
work_sheet.append(generate_stats_row('25%', region_size, 'PERCENTILE', len(patient_list), ',0.25'))
work_sheet.append(generate_stats_row('50%', region_size, 'PERCENTILE', len(patient_list), ',0.50'))
work_sheet.append(generate_stats_row('75%', region_size, 'PERCENTILE', len(patient_list), ',0.75'))
work_sheet.append(generate_stats_row('95%', region_size, 'PERCENTILE', len(patient_list), ',0.95'))
work_sheet.append(generate_stats_row('最大值', region_size, 'MAX', len(patient_list), ''))
def write_anova(workbook, work_sheet, groups, atlas, data_type):
header = ['', 'F', 'p']
work_sheet.append(header)
sheet_dict = {}
for group_name, group in groups.items():
sheet_dict[group_name] = f'{group_name}_{atlas}_{data_type}'
first_group_sheet = workbook[list(sheet_dict.values())[0]]
for column_num in range(2, first_group_sheet.max_column + 1):
data_list = []
data_row = [first_group_sheet.cell(row=1, column=column_num).value]
for group_name, sheet_name in sheet_dict.items():
group_data = []
data_count = len(groups[group_name])
for i in range(2, data_count + 2):
data_value = workbook[sheet_name].cell(row=i, column=column_num).value
if not np.isnan(data_value):
group_data.append(data_value)
data_list.append(group_data)
if len(data_list[0]) == 0:
continue
f_value, p_value = f_oneway(*data_list)
data_row += [f_value, p_value]
work_sheet.append(data_row)
def main():
data_types = ['corr-CBF']
atlas_list = ['AnImage_AAL3']
output_file = r'..\Data\csv-ANOVA-SciPy.xlsx'
group_file = r'..\Data\group.xlsx'
patient_root = r'..\Data\csv-data'
groups = {}
group_workbook = openpyxl.load_workbook(group_file)
for sheet_name in group_workbook.sheetnames:
group = []
group_sheet = group_workbook[sheet_name]
for i in range(1, group_sheet.max_row + 1):
patient_id = group_sheet.cell(row=i, column=1).value
patient_path = os.path.join(patient_root, patient_id)
group.append(patient_path)
groups[sheet_name] = group
all_group = []
for group in groups.values():
all_group += group
work_book = openpyxl.Workbook()
work_book.remove(work_book.active)
for data_type in data_types:
for atlas in atlas_list:
atlas_new_name = atlas.replace("AnImage_", "")
for group_key in groups.keys():
work_sheet = work_book.create_sheet(title=f'{group_key}_{atlas_new_name}_{data_type}')
write_to_work_sheet(work_sheet, groups[group_key], atlas, data_type)
work_sheet = work_book.create_sheet(title=f'ALL_{atlas_new_name}_{data_type}')
write_to_work_sheet(work_sheet, all_group, atlas, data_type)
for data_type in data_types:
for atlas in atlas_list:
atlas_new_name = atlas.replace("AnImage_", "")
work_sheet = work_book.create_sheet(title=f'ANOVA_{atlas_new_name}_{data_type}')
write_anova(work_book, work_sheet, groups, atlas_new_name, data_type)
work_book.save(output_file)
main()