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

PyQt5 CSV数据展示异常:无法识别Pandas iloc合法输入格式

解决Pandas iloc合法输入无法识别及多CSV拼接问题

问题现状

原需求为:读取目录下多个CSV文件,转为独立Pandas DataFrame后拼接,通过QLineEdit控件输入iloc格式的行列筛选条件,在QTableWidget中展示结果;若输入无效则弹出错误提示。但现有代码存在以下问题:

  • 仅读取第一个CSV文件,未实现多文件拼接
  • 使用eval(f'{data_DF}.iloc{row_col_input}')的错误方式,无法解析iloc的各类合法输入(如[[0]]、[:3]、[[0,2],[1,3]]等)
  • Series类型数据的展示逻辑不合理,无法正确显示单行多列或单列多行的结果

问题根源

将DataFrame对象直接转为字符串插入eval表达式,相当于在eval中处理的是DataFrame的字符串表示,而非实际的DataFrame变量,自然无法正确调用iloc方法。

修改后的完整代码

1. 修复多CSV读取与拼接的loadFiles函数

def loadFiles(self):
    options = QFileDialog.Options()
    options |= QFileDialog.ReadOnly
    fileNames, _ = QFileDialog.getOpenFileNames(None, "选择CSV文件", "",
                                                "CSV Files (*.csv);;All Files (*)", options=options)
    if fileNames:
        # 读取多个CSV并转为DataFrame列表
        df_list = []
        for fileName in fileNames:
            # 用pandas直接读取CSV,自动处理表头和数据类型(若CSV有表头可移除header=None)
            df = pd.read_csv(fileName, header=None)
            df_list.append(df)
        # 拼接所有DataFrame,重置行索引
        data_DF = pd.concat(df_list, ignore_index=True)
        self.displayData(data_DF)

说明:

  • 用pd.read_csv替代原生csv模块,更简洁且能自动处理数据类型
  • 用pd.concat实现多DataFrame的纵向拼接,ignore_index=True避免索引冲突

2. 修复iloc解析与数据展示的displayData函数

def displayData(self, data_DF):
    row_col_input = self.lineEdit_4.text().strip()
    # 输入为空时展示全部数据
    if not row_col_input:
        selected_data = data_DF
    else:
        try:
            # 拆分解析iloc的索引参数,兼容单/双维度输入
            if ',' in row_col_input:
                # 双维度输入:行, 列
                row_part, col_part = row_col_input.split(',', 1)
                # 处理切片(如:3)和列表索引(如[0,2])
                row_idx = eval(f"slice({row_part.strip().strip('[]')})" if ':' in row_part else row_part.strip())
                col_idx = eval(f"slice({col_part.strip().strip('[]')})" if ':' in col_part else col_part.strip())
                selected_data = data_DF.iloc[row_idx, col_idx]
            else:
                # 单维度输入:默认筛选行
                idx = eval(f"slice({row_col_input.strip().strip('[]')})" if ':' in row_col_input else row_col_input.strip())
                selected_data = data_DF.iloc[idx]
        except Exception as e:
            # 捕获解析错误,弹出提示(调试时可打印错误详情)
            print(f"输入解析错误:{str(e)}")
            QMessageBox.warning(self, "错误", "无效的iloc输入格式,请检查输入")
            return

    # 清空表格,准备填充新数据
    self.tableView.clear()
    # 兼容DataFrame、Series、单个值的展示逻辑
    if isinstance(selected_data, pd.DataFrame):
        rows = selected_data.values.tolist()
        self.tableView.setRowCount(len(rows))
        self.tableView.setColumnCount(selected_data.shape[1])
        # 设置表头(若不需要可移除)
        self.tableView.setHorizontalHeaderLabels([str(col) for col in selected_data.columns])
        for i, row in enumerate(rows):
            for j, val in enumerate(row):
                self.tableView.setItem(i, j, QTableWidgetItem(str(val)))
    elif isinstance(selected_data, pd.Series):
        if selected_data.ndim == 1:
            if len(selected_data) == selected_data.index.size:
                # 单列多行数据
                self.tableView.setRowCount(len(selected_data))
                self.tableView.setColumnCount(1)
                for i, val in enumerate(selected_data.values):
                    self.tableView.setItem(i, 0, QTableWidgetItem(str(val)))
                self.tableView.setHorizontalHeaderLabels([str(selected_data.name)])
            else:
                # 单行多列数据
                self.tableView.setRowCount(1)
                self.tableView.setColumnCount(len(selected_data))
                for j, val in enumerate(selected_data.values):
                    self.tableView.setItem(0, j, QTableWidgetItem(str(val)))
                self.tableView.setHorizontalHeaderLabels([str(col) for col in selected_data.index])
    else:
        # 单个值的情况
        self.tableView.setRowCount(1)
        self.tableView.setColumnCount(1)
        self.tableView.setItem(0, 0, QTableWidgetItem(str(selected_data)))

说明:

  • 移除了不安全的整体eval,改为拆分解析iloc的索引参数,兼容切片、列表等各类合法输入
  • 完善了Series类型数据的展示逻辑,自动区分单列多行和单行多列的场景
  • 输入为空时默认展示全部数据,提升用户体验
  • 异常处理更精准,仅捕获输入解析错误,避免掩盖其他代码问题

输入格式示例

支持的iloc输入格式包括:

  • 单维度行筛选:[:3]、[[0,2]]、[1]
  • 双维度行列筛选:[1:3, 0:3]、[[0,2],[1,3]]、[0, :]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:13:59