Pandas Pyqt 实现 table 过滤排序
Pandas Pyqt implement table filter sort
我正在尝试在 Pyqt 应用程序中实现一些 Pandas GUI。
我找到了一个 class 来在 PyQt table 中加载 Pandas DF。
现在我希望能够过滤这些数据(即像 excel 那样)并相应地生成 df。
然而 Pyqt 对我来说有点陡峭,我不喜欢实现它,如果它很困难(我很惊讶它还不存在)
请在下面找到我的代码
任何建议或意见将不胜感激
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore, QtGui
import pandas as pd
import numpy as np
data = {'col1':['1','2','3'], 'col2':['4','5','6'], 'col3':['7','8','9']}
head807677=['Date','Heure','OK-NOK','Detect','C1','C2','C3','C4','C5','C6','C7']
head801986=['Date','Heure','Ok-NOK','Detect','C1','C2','C3','C4','C5','C6','C7','C8']
head=head807677
class PandasModel(QtCore.QAbstractTableModel):
"""
Class to populate a table view with a pandas dataframe
"""
def __init__(self, data, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
self._data = data
def rowCount(self, parent=None):
return len(self._data.values)
def columnCount(self, parent=None):
return self._data.columns.size
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid():
if role == QtCore.Qt.DisplayRole:
return str(self._data.values[index.row()][index.column()])
return None
def headerData(self, col, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self._data.columns[col]
return None
class QMT(QtGui.QMainWindow):
def __init__(self, parent=None):
super(QMT, self).__init__(parent)
#self.table=QMyTable(data,5,3)
self.view = QtGui.QTableView(self)
self.setCentralWidget(self.view)
self.view.show()
self.initUI()
def initUI(self):
exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(QtGui.qApp.quit)
openFile = QtGui.QAction(QtGui.QIcon('open.png'), 'Open', self)
openFile.setShortcut('Ctrl+O')
openFile.setStatusTip('Open new File')
openFile.triggered.connect(self.showDialog)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
fileMenu.addAction(openFile)
self.statusBar()
self.setGeometry(200, 200, 400, 400)
self.setWindowTitle('Menubar')
self.show()
def showDialog(self):
fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
'C:/Users/user11.HPO-SAMAT/Desktop/807677')
data=self.file2df(fname)
data.columns=head
self.model = PandasModel(data)
self.view.setModel(self.model)
self.view.show()
def file2df(self,elmnt):
data=pd.read_csv(elmnt,names=head,
sep='\t+',
index_col=False,
header=None
)
data=data[data['Detect']==True]
return data
def main(args):
app = QApplication(args)
win = QMT()
win.show()
app.exec_()
if __name__=="__main__":
main(sys.argv)
少量修改:
使用 numpy 更改 PandasMadel => 真的更快,请参阅此处
class PandasModel(QtCore.QAbstractTableModel):
"""
Class to populate a table view with a pandas dataframe
"""
def __init__(self, data, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
self._data = np.array(data.values)
self._cols = data.columns
self.r, self.c = np.shape(self._data)
def rowCount(self, parent=None):
return self.r
def columnCount(self, parent=None):
return self.c
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid():
if role == QtCore.Qt.DisplayRole:
return self._data[index.row(),index.column()]
return None
def headerData(self, p_int, orientation, role):
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
return self._cols[p_int]
elif orientation == QtCore.Qt.Vertical:
return p_int
return None
然后主要 class:
class QMT(QtGui.QMainWindow):
def __init__(self, parent=None):
super(QMT, self).__init__(parent)
self.view = QtGui.QTableView(self)
self.header = self.view.horizontalHeader()
self.header.sectionClicked.connect(self.headerClicked)
.....
和排序操作(在 DF 上,但之后我需要使用 DF)
def headerClicked(self, logicalIndex):
self.order = self.header.sortIndicatorOrder()
self.pdata.sort(self.pdata.columns[logicalIndex],
ascending=self.order,inplace=True)
self.model = PandasModel(self.pdata)
self.view.setModel(self.model)
self.view.update()
我正在尝试在 Pyqt 应用程序中实现一些 Pandas GUI。 我找到了一个 class 来在 PyQt table 中加载 Pandas DF。 现在我希望能够过滤这些数据(即像 excel 那样)并相应地生成 df。 然而 Pyqt 对我来说有点陡峭,我不喜欢实现它,如果它很困难(我很惊讶它还不存在)
请在下面找到我的代码 任何建议或意见将不胜感激
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore, QtGui
import pandas as pd
import numpy as np
data = {'col1':['1','2','3'], 'col2':['4','5','6'], 'col3':['7','8','9']}
head807677=['Date','Heure','OK-NOK','Detect','C1','C2','C3','C4','C5','C6','C7']
head801986=['Date','Heure','Ok-NOK','Detect','C1','C2','C3','C4','C5','C6','C7','C8']
head=head807677
class PandasModel(QtCore.QAbstractTableModel):
"""
Class to populate a table view with a pandas dataframe
"""
def __init__(self, data, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
self._data = data
def rowCount(self, parent=None):
return len(self._data.values)
def columnCount(self, parent=None):
return self._data.columns.size
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid():
if role == QtCore.Qt.DisplayRole:
return str(self._data.values[index.row()][index.column()])
return None
def headerData(self, col, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self._data.columns[col]
return None
class QMT(QtGui.QMainWindow):
def __init__(self, parent=None):
super(QMT, self).__init__(parent)
#self.table=QMyTable(data,5,3)
self.view = QtGui.QTableView(self)
self.setCentralWidget(self.view)
self.view.show()
self.initUI()
def initUI(self):
exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(QtGui.qApp.quit)
openFile = QtGui.QAction(QtGui.QIcon('open.png'), 'Open', self)
openFile.setShortcut('Ctrl+O')
openFile.setStatusTip('Open new File')
openFile.triggered.connect(self.showDialog)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
fileMenu.addAction(openFile)
self.statusBar()
self.setGeometry(200, 200, 400, 400)
self.setWindowTitle('Menubar')
self.show()
def showDialog(self):
fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file',
'C:/Users/user11.HPO-SAMAT/Desktop/807677')
data=self.file2df(fname)
data.columns=head
self.model = PandasModel(data)
self.view.setModel(self.model)
self.view.show()
def file2df(self,elmnt):
data=pd.read_csv(elmnt,names=head,
sep='\t+',
index_col=False,
header=None
)
data=data[data['Detect']==True]
return data
def main(args):
app = QApplication(args)
win = QMT()
win.show()
app.exec_()
if __name__=="__main__":
main(sys.argv)
少量修改:
使用 numpy 更改 PandasMadel => 真的更快,请参阅此处
class PandasModel(QtCore.QAbstractTableModel):
"""
Class to populate a table view with a pandas dataframe
"""
def __init__(self, data, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
self._data = np.array(data.values)
self._cols = data.columns
self.r, self.c = np.shape(self._data)
def rowCount(self, parent=None):
return self.r
def columnCount(self, parent=None):
return self.c
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid():
if role == QtCore.Qt.DisplayRole:
return self._data[index.row(),index.column()]
return None
def headerData(self, p_int, orientation, role):
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
return self._cols[p_int]
elif orientation == QtCore.Qt.Vertical:
return p_int
return None
然后主要 class:
class QMT(QtGui.QMainWindow):
def __init__(self, parent=None):
super(QMT, self).__init__(parent)
self.view = QtGui.QTableView(self)
self.header = self.view.horizontalHeader()
self.header.sectionClicked.connect(self.headerClicked)
.....
和排序操作(在 DF 上,但之后我需要使用 DF)
def headerClicked(self, logicalIndex):
self.order = self.header.sortIndicatorOrder()
self.pdata.sort(self.pdata.columns[logicalIndex],
ascending=self.order,inplace=True)
self.model = PandasModel(self.pdata)
self.view.setModel(self.model)
self.view.update()