PySimpleGUI调用内部函数后CSV表格列名不更新问题求助
PySimpleGUI表格更新后新增列名不显示的问题解决思路
问题背景
执行流程:
- 上传CSV文件并创建可编辑的CSV窗口
- 点击「Calculate Diplotype」按钮,调用内部函数
diplotype_calc() - 尝试用处理后的DataFrame更新CSV窗口
问题:数据已按预期处理完成,但CSV窗口始终保留初始上传时的列名,新增的「Metabolizer Status」和「Activity Score」列名无法显示。
相关代码
import PySimpleGUI as sg import webview import pandas as pd import csv import os import operator import tkinter as tk from tkinter import filedialog import tkinter.messagebox # Diplotype Calculator Functions def diplotype_calc(file_path): data, allele_cols = read_csv_file(file_path) allele_df = pd.DataFrame(data, columns=allele_cols)[['sample ID', 'CYP2D6', 'CYP2C9']] print(allele_df) # Import CPIC dataframe from Google Cloud Storage into pandas dataframe # Currently only supported for CYP2D6 and CYP2C9 cpic_data = f'https://storage.googleapis.com/pg-genotyping-cpic-2d6-2d9/2d6_2d9_joined.csv' cpic_df = pd.read_csv(cpic_data) # Merge the two DataFrames based on the common columns CYP2D6 and CYP2C9 merged_df = pd.merge(allele_df, cpic_df, on=['CYP2D6', 'CYP2C9']) # Create two new columns to store the Metabolizer Status and Activity Score merged_df['Metabolizer Status'] = '' merged_df['Activity Score'] = '' # Create two dictionaries to store the metabolizer status and activity score for each call d6_status_dict = dict(zip(cpic_df['CYP2D6'], cpic_df['Metabolizer Status'])) d9_status_dict = dict(zip(cpic_df['CYP2C9'], cpic_df['Metabolizer Status'])) d6_activity_dict = dict(zip(cpic_df['CYP2D6'], cpic_df['Activity Score'])) d9_activity_dict = dict(zip(cpic_df['CYP2C9'], cpic_df['Activity Score'])) # Create two new columns to store the Metabolizer Status and Activity Score allele_df['Metabolizer Status'] = '' allele_df['Activity Score'] = '' # Iterate over each row of the allele DataFrame for index, row in allele_df.iterrows(): # Get the cyp2d6 and cyp2c9 calls for the current sample ID cyp2d6_call = row['CYP2D6'] cyp2c9_call = row['CYP2C9'] # Use the dictionaries to get the metabolizer status and activity score for the current calls cyp2d6_status = d6_status_dict.get(cyp2d6_call, 'UND') cyp2c9_status = d9_status_dict.get(cyp2c9_call, 'UND') cyp2d6_activity = d6_activity_dict.get(cyp2d6_call, 'UND') cyp2c9_activity = d9_activity_dict.get(cyp2c9_call, 'UND') # Use the comparison results to populate the Metabolizer Status and Activity Score columns of the allele DataFrame allele_df.loc[index, 'Metabolizer Status'] = f'2D6: {cyp2d6_status} ||| 2C9: {cyp2c9_status}' allele_df.loc[index, 'Activity Score'] = f'{cyp2d6_activity}, {cyp2c9_activity}' # convert all of the updated data back into a list of lists updated_data = allele_df.values.tolist() # save_loc(allele_df) print(updated_data) window['-TABLE-'].update(values=updated_data) csv_window(updated_data)
问题分析与解决思路
核心原因
PySimpleGUI的Table组件需要同时更新**行数据(values)和表头列名(headings)**才能完整展示新增列。当前代码仅更新了行数据,未同步更新表头,导致新增列的名称无法显示。
具体修复步骤
获取更新后的列名列表
在生成updated_data后,从处理后的DataFrame中提取最新列名:updated_headings = allele_df.columns.tolist()更新现有Table组件的表头和数据
修改window['-TABLE-'].update()的调用,同时传入headings参数:window['-TABLE-'].update(values=updated_data, headings=updated_headings)修改
csv_window函数的调用与实现- 调用时传入新列名:
csv_window(updated_data, updated_headings) - 确保
csv_window函数内部在创建或更新Table时,使用传入的updated_headings而非初始列名。例如,若csv_window是新建窗口,需在sg.Table的参数中指定headings=updated_headings;若更新现有窗口,需执行类似table_element.update(headings=updated_headings)的操作。
- 调用时传入新列名:
额外优化建议
- 代码中
merged_df对象创建后未被使用,可删除以减少冗余; - 使用
iterrows()循环逐行赋值效率较低,建议改用pandas的向量操作或apply方法优化,例如:allele_df['Metabolizer Status'] = allele_df.apply( lambda row: f"2D6: {d6_status_dict.get(row['CYP2D6'], 'UND')} ||| 2C9: {d9_status_dict.get(row['CYP2C9'], 'UND')}", axis=1 ) allele_df['Activity Score'] = allele_df.apply( lambda row: f"{d6_activity_dict.get(row['CYP2D6'], 'UND')}, {d9_activity_dict.get(row['CYP2C9'], 'UND')}", axis=1 )
内容的提问来源于stack exchange,提问作者ClarkThark
相关产品推荐
相关产品推荐

