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

继承ReportQueryCommand实现多Excel输出的AttributeError解决

问题解决:AttributeError与多Excel文件输出支持

问题详情

报错信息:

self.filtered_df.to_excel(self.output_filepath, index=False)
AttributeError: 'tuple' object has no attribute 'to_excel'

根源是自定义TtestStrategy类的transform方法返回了两个DataFrame组成的元组,但父类ReportQueryCommand的write_to_file方法仅支持处理单个DataFrame对象,无法识别元组类型。需要修改write_to_file方法,使其支持输出多个Excel文件。

修改方案

1. 升级write_to_file方法,兼容单个/多个DataFrame

修改父类ReportQueryCommand的write_to_file方法,自动判断filtered_df的类型并分别处理:

import os
import pandas as pd

def write_to_file(self):
    if self.filtered_df is None:
        raise ValueError("Missing computed dataframe")
    
    # 处理单个DataFrame的情况
    if isinstance(self.filtered_df, pd.DataFrame):
        self.filtered_df.to_excel(self.output_filepath, index=False)
    # 处理多个DataFrame的情况(元组或列表)
    elif isinstance(self.filtered_df, (tuple, list)):
        # 拆分文件路径和扩展名
        base_path, ext = os.path.splitext(self.output_filepath)
        # 获取策略定义的输出键作为文件名后缀(无定义则用序号)
        strategy_keys = getattr(self.strategy, "_strategy_key", lambda: tuple(range(len(self.filtered_df))))()
        # 遍历生成对应文件
        for idx, df in enumerate(self.filtered_df):
            if isinstance(df, pd.DataFrame):
                suffix = strategy_keys[idx] if isinstance(strategy_keys, (tuple, list)) else idx
                new_filepath = f"{base_path}_{suffix}{ext}"
                df.to_excel(new_filepath, index=False)
    else:
        raise TypeError(f"Unsupported type for filtered_df: {type(self.filtered_df)}")

2. 调整状态存储逻辑(可选)

原execute方法将filtered_df直接存入状态字典,如果是多个DataFrame,建议存储为字典结构方便后续调用:

def execute(self, output_from_previous: Any = None, **kwargs) -> Any:
    self.filtered_df = self.strategy.transform(key=self.key_input,
                                               df=self.df_to_filter)
    # 适配多DataFrame的状态存储
    if isinstance(self.filtered_df, (tuple, list)):
        strategy_keys = getattr(self.strategy, "_strategy_key", lambda: tuple(range(len(self.filtered_df))))()
        self.state.query_reports[self.key_output] = {
            key: df for key, df in zip(strategy_keys, self.filtered_df)
            if isinstance(df, pd.DataFrame)
        }
    else:
        self.state.query_reports[self.key_output] = self.filtered_df
    super().execute(output_from_previous=output_from_previous, **kwargs)

3. 利用策略类的_strategy_key优化命名

TtestStrategy的_strategy_key已经返回tuple('t-test', 'fisher-test'),刚好对应两个返回的DataFrame,修改后会自动生成如原文件名_t-test.xlsx、原文件名_fisher-test.xlsx的可读性文件名。

修改后效果

运行代码时,TtestStrategy返回的两个DataFrame会分别保存为独立的Excel文件,同时完全兼容原有仅返回单个DataFrame的策略类,不破坏现有功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:45:33