Можно ли задействовать панель поиска в DataFrame в Pandas? - PullRequest
1 голос
/ 28 мая 2020

Извините, если это глупый вопрос, но поскольку я ничего не нашел в inte rnet (или, может быть, я не искал правильно), я решил разместить здесь свой вопрос и проблему.

I есть DataFrame в Pandas, который собирает некоторые данные из документа Excel. Я создал GUI с PyQt5, чтобы он выглядел более интересным, но вот в чем дело.

Можно ли создать динамическую панель поиска c для поиска в этом DataFrame? Например, мой DataFrame имеет более 3k + строк, и я хочу найти John Doe, тогда результаты появятся на GUI. Насколько мне известно, для этого используется QLineEdit, но я не могу реализовать его в своем коде.

Это я делаю неправильно, или это невозможно сделать в DataFrame? И если кто-нибудь захочет мне помочь, просто дайте мне знать, я был бы так благодарен и благодарен, думаю, это займет всего 10-15 минут. Я также могу опубликовать код здесь, но говорить о Discord и подробно объяснять вам, а также делиться экранами было бы намного проще.

Заранее спасибо, братья, и позаботьтесь о вас !!

изменить: опечатка

1 Ответ

1 голос
/ 28 мая 2020

Это можно сделать путем создания подкласса QAbstractTableModel для создания пользовательской модели таблицы, которая использует базовый фрейм данных для передачи данных в QTableView. Затем эту пользовательскую модель можно комбинировать с QProxyFilterSortModel для фильтрации данных в таблице. Чтобы создать настраиваемую нередактируемую модель из QAbstractTableModel, вам необходимо реализовать как минимум rowCount, columnCount, data и headerData. В этом случае минимальная реализация может быть примерно такой:

class DataFrameModel(QtCore.QAbstractTableModel):
    def __init__(self, data_frame, parent = None):
        super().__init__(parent)
        self.data_frame = data_frame

    def rowCount(self, index):
        if index.isValid():
            return 0
        return self.data_frame.shape[0]

    def columnCount(self, index):
        if index.isValid():
            return 0
        return self.data_frame.shape[1]

    def data(self, index, role):
        if not index.isValid() or role != QtCore.Qt.DisplayRole:
            return None
        return str(self.data_frame.iloc[index.row(), index.column()])

    def headerData(self, section, orientation, role=None):
        if role != QtCore.Qt.DisplayRole:
            return None
        if orientation == QtCore.Qt.Vertical:
            return self.data_frame.index[section]
        else:
            return self.data_frame.columns[section]

Чтобы отобразить и отфильтровать данные в таблице, вы можете сделать что-то вроде этого:

class MyWidget(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.table_view = QtWidgets.QTableView()

        self.proxy_model = QtCore.QSortFilterProxyModel()
        # by default, the QSortFilterProxyModel will search for keys in the first column only
        # setting QSortFilterProxyModel.filterKeyColumn to -1 will match values in all columns
        self.proxy_model.setFilterKeyColumn(-1)
        self.table_view.setModel(self.proxy_model)

        # line edit for entering (part of) the key that should be searched for
        self.line_edit = QtWidgets.QLineEdit()
        self.line_edit.textChanged.connect(self.filter_text)

        vlayout = QtWidgets.QVBoxLayout(self)
        vlayout.addWidget(self.line_edit)
        vlayout.addWidget(self.table_view)

    def filter_text(self, text):
        self.proxy_model.setFilterFixedString(text)

    def set_data(self, data):
        self.model = DataFrameModel(pd.DataFrame(data))
        self.proxy_model.setSourceModel(self.model)



if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    win = MyWidget()
    win.set_data({'a':['apple', 'banana', 'cherry'], 'b':[4,5,6], 'c':['green', 'yellow', 'red']})
    win.show()
    app.exec()

Конечно, это очень простая реализация c, но я могу помочь вам начать работу.

...