⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 owselectdata.py

📁 orange源码 数据挖掘技术
💻 PY
📖 第 1 页 / 共 3 页
字号:
"""
<name>Select Data</name>
<description>Selects instances from the data set based on conditions over attributes.</description>
<icon>icons/SelectData.png</icon>
<priority>1150</priority>
<contact>Peter Juvan (peter.juvan@fri.uni-lj.si)</contact>
"""

import orange
from OWWidget import *
from qttable import *
import OWGUI


class OWSelectData(OWWidget):

    # loadedConditions and loadedVarNames saved the last conditions, but they failed to show
    # in the table when they are reloaded!
    # I removed them; we shall have the context settings doing that some day
    settingsList = ["updateOnChange", "purgeAttributes", "purgeClasses"]#, "loadedConditions", "loadedVarNames"]

    def __init__(self, parent = None, signalManager = None, name = "Select data"):
        OWWidget.__init__(self, parent, signalManager, name)  #initialize base class

        # set channels
        self.inputs = [("Examples", ExampleTable, self.onDataInput)]
        self.outputs = [("Matching Examples", ExampleTable, Default), ("Non-Matching Examples", ExampleTable), ("Matching Classified Examples", ExampleTableWithClass, Default), ("Non-Matching Classified Examples", ExampleTableWithClass)]

        # manually set member variables
        self.name2var = {}   # key: variable name, item: orange.Variable
        self.Conditions = []

        # handled member variables
        self.currentVar = None
        self.NegateCondition = False
        self.currentOperatorDict = {orange.VarTypes.Continuous:Operator(Operator.operatorsC[0], orange.VarTypes.Continuous),
                                    orange.VarTypes.Discrete:Operator(Operator.operatorsD[0],orange.VarTypes.Discrete),
                                    orange.VarTypes.String:Operator(Operator.operatorsS[0], orange.VarTypes.String)}
        self.Num1 = 0.0
        self.Num2 = 0.0
        self.Str1 = ""
        self.Str2 = ""
        self.currentVals = []
        self.CaseSensitive = False
        self.updateOnChange = True
        self.purgeAttributes = True
        self.purgeClasses = True
        self.oldPurgeClasses = True

        # load settings
        self.loadedVarNames = []
        self.loadedConditions = []
        self.loadSettings()
        
        # GUI
        self.mainArea.setFixedWidth(0)
        ca=QFrame(self.controlArea)
        ca.adjustSize()
        gl=QGridLayout(ca,4,3,5)

        # attribute condition box
        boxAttrCond = QVGroupBox('Attribute Condition', ca)
        gl.addMultiCellWidget(boxAttrCond, 0,0,0,2)
        frmAttrCond = QFrame(boxAttrCond)
        frmAttrCond.adjustSize()
        glac=QGridLayout(frmAttrCond,1,3,5)
        glac.setColStretch(0,2)
        glac.setColStretch(1,1)
        glac.setColStretch(2,2)

        # attributes
        boxAttr = QVGroupBox(frmAttrCond)
        glac.addWidget(boxAttr,0,0)
        boxAttr.setTitle('Attribute')
        self.lbAttr = QListBox(boxAttr, 'SelAttr')
        self.connect(self.lbAttr, SIGNAL('selectionChanged()'), self.lbAttrChange)

        sbox = QHBox(boxAttr)
        QLabel("Search: ", sbox)
        self.leSelect = QLineEdit(sbox)
        self.connect(self.leSelect, SIGNAL('textChanged(const QString &)'), self.setLbAttr)

        # operators
        boxOper = QVGroupBox('Operator', frmAttrCond)
        # operators 0: empty
        self.lbOperatosNone = QListBox(boxOper, 'SelAttr')
        # operators 1: discrete
        self.lbOperatorsD = QListBox(boxOper, 'SelAttr')
        self.lbOperatorsD.hide()
        self.connect(self.lbOperatorsD, SIGNAL('selectionChanged()'), self.lbOperatorsChange)
        for op in Operator.operatorsD + [Operator.operatorDef]:
            self.lbOperatorsD.insertItem(op)
        # operators 2: continuous
        self.lbOperatorsC = QListBox(boxOper, 'SelAttr')
        self.lbOperatorsC.hide()
        self.connect(self.lbOperatorsC, SIGNAL('selectionChanged()'), self.lbOperatorsChange)
        for op in Operator.operatorsC + [Operator.operatorDef]:
            self.lbOperatorsC.insertItem(op)
        # operators 6: string
        self.lbOperatorsS = QListBox(boxOper, 'SelAttr')
        self.lbOperatorsS.hide()
        self.connect(self.lbOperatorsS, SIGNAL('selectionChanged()'), self.lbOperatorsChange)
        for op in Operator.operatorsS + [Operator.operatorDef]:
            self.lbOperatorsS.insertItem(op)
        self.lbOperatorsDict = {0: self.lbOperatosNone,
                                orange.VarTypes.Continuous: self.lbOperatorsC,
                                orange.VarTypes.Discrete: self.lbOperatorsD,
                                orange.VarTypes.String: self.lbOperatorsS}
        # NOT checkbox
        glac.addWidget(boxOper,0,1)
        self.cbNot = OWGUI.checkBox(boxOper, self, "NegateCondition", "NOT")

        # values
        self.valuesStack = QWidgetStack(frmAttrCond)
        glac.addWidget(self.valuesStack,0,2)
        # values 0: empty
        boxVal = QVGroupBox("Values", None)
        self.valuesStack.addWidget(boxVal, 0)
        # values 2: continuous between num and num
        boxVal = QVGroupBox("Values", None)
        self.valuesStack.addWidget(boxVal, orange.VarTypes.Continuous)
        self.leNum1 = OWGUI.lineEdit(boxVal, self, "Num1")
        self.lblAndCon = OWGUI.widgetLabel(boxVal, "and")
        self.leNum2 = OWGUI.lineEdit(boxVal, self, "Num2")
        boxAttrStat = QVGroupBox("Statistics", boxVal)
        self.lblMin = QLabel("Min: ", boxAttrStat)
        self.lblAvg = QLabel("Avg: ", boxAttrStat)
        self.lblMax = QLabel("Max: ", boxAttrStat)
        self.lblDefined = QLabel("Defined for ---- examples", boxAttrStat)
        # values 1: discrete
        boxVal = QVGroupBox("Values", None)
        self.valuesStack.addWidget(boxVal, orange.VarTypes.Discrete)
        self.lbVals = QListBox(boxVal)
        self.connect(self.lbVals , SIGNAL('selectionChanged()'), self.lbValsChange)
        # values 6: string between str and str
        boxVal = QVGroupBox("Values", None)
        self.valuesStack.addWidget(boxVal, orange.VarTypes.String)
        self.leStr1 = OWGUI.lineEdit(boxVal, self, "Str1")
        self.lblAndStr = OWGUI.widgetLabel(boxVal, "and")
        self.leStr2 = OWGUI.lineEdit(boxVal, self, "Str2")
        self.cbCaseSensitive = OWGUI.checkBox(boxVal, self, "CaseSensitive", "Case sensitive")

        # buttons Add, Update, Remove, Disjunction, Up, Down
        self.boxButtons = QHBox(ca)
        gl.addMultiCellWidget(self.boxButtons, 1,1,0,2)
        self.btnNew = OWGUI.button(self.boxButtons, self, "Add", self.OnNewCondition)
        self.btnUpdate = OWGUI.button(self.boxButtons, self, "Update", self.OnUpdateCondition)
        self.btnRemove = OWGUI.button(self.boxButtons, self, "Remove", self.OnRemoveCondition)        
        self.btnOR = OWGUI.button(self.boxButtons, self, "OR", self.OnDisjunction)        
        self.btnMoveUp = OWGUI.button(self.boxButtons, self, "Move Up", self.btnMoveUpClicked)        
        self.btnMoveDown = OWGUI.button(self.boxButtons, self, "Move Down", self.btnMoveDownClicked)
        self.btnRemove.setEnabled(False)
        self.btnUpdate.setEnabled(False)
        self.btnMoveUp.setEnabled(False)
        self.btnMoveDown.setEnabled(False)

        # data selection criteria
        boxCriteria = QVGroupBox(ca)
        boxCriteria.setTitle('Data Selection Criteria')
        gl.addMultiCellWidget(boxCriteria, 2,2,0,2)
        self.criteriaTable = QTable(boxCriteria)
        self.criteriaTable.setShowGrid(False)
        self.criteriaTable.setSelectionMode(QTable.NoSelection)
        self.criteriaTable.setNumCols(2)
        self.criteriaTable.verticalHeader().setClickEnabled(False)
        self.criteriaTable.verticalHeader().setResizeEnabled(False,-1)
        hheader=self.criteriaTable.horizontalHeader()
        hheader.setClickEnabled(False)
        hheader.setLabel(0, "Active      ")
        hheader.setLabel(1, "Condition")
        self.connect(self.criteriaTable, SIGNAL('currentChanged(int, int)'), self.currentCriteriaChange)
        self.criteriaTable.adjustColumn(0)
        self.criteriaTable.setColumnWidth(1, 360)

        # data in
        boxDataIn = QVGroupBox(ca)
        boxDataIn.setTitle('Data In')
        gl.addWidget(boxDataIn, 3,0)
        self.dataInExamplesLabel = OWGUI.widgetLabel(boxDataIn, "num examples")
        self.dataInAttributesLabel = OWGUI.widgetLabel(boxDataIn, "num attributes")

        # data out
        boxDataOut = QVGroupBox(ca)
        boxDataOut.setTitle('Data Out')
        gl.addWidget(boxDataOut, 3,1)        
        self.dataOutExamplesLabel = OWGUI.widgetLabel(boxDataOut, "num examples")
        self.dataOutAttributesLabel = OWGUI.widgetLabel(boxDataOut, "num attributes")

        # update
        boxSettings = QVGroupBox(ca)
        boxSettings.setTitle('Update')
        gl.addWidget(boxSettings, 3,2)
        OWGUI.checkBox(boxSettings, self, "purgeAttributes", "Remove unused values/attributes", box=None, callback=self.OnPurgeChange)
        self.purgeClassesCB = OWGUI.checkBox(OWGUI.indentedBox(boxSettings), self, "purgeClasses", "Remove unused classes", callback=self.OnPurgeChange)
        OWGUI.checkBox(boxSettings, self, "updateOnChange", "Update on any change", box=None)
        btnUpdate = OWGUI.button(boxSettings, self, "Update", self.setOutput)

        # icons
        self.icons = self.createAttributeIconDict()
        self.onDataInput(None)
        self.lbOperatorsD.setCurrentItem(0)
        self.lbOperatorsC.setCurrentItem(0)
        self.lbOperatorsS.setCurrentItem(0)
        self.resize(500,661)


    ############################################################################################################################################################
    ## Data input and output management ########################################################################################################################
    ############################################################################################################################################################

    def onDataInput(self, data):
        """Loads stored conditions (if we have a similar domain), updates list boxes and data in info, sends out data.
        """
        self.data = data
        self.bas = orange.DomainBasicAttrStat(data)
        if self.data:
            # set self.name2var
            optmetas = self.data.domain.getmetas(True).values()
            optmetas.sort(lambda x,y: cmp(x.name, y.name))
            self.varList = self.data.domain.variables.native() + self.data.domain.getmetas(False).values() + optmetas
            varNames = []
            for v in self.varList:
                self.name2var[v.name] = v
                varNames.append(v.name)
            if varNames == self.loadedVarNames:
                if self.Conditions == []:
                    self.Conditions = self.loadedConditions
            else:
                self.loadedVarNames = varNames

                # clear conditions and criteria table
                self.Conditions = []
                for row in range(self.criteriaTable.numRows()-1,-1,-1):
                    self.criteriaTable.clearCellWidget(row,0)
                    self.criteriaTable.clearCell(row,1)
                    self.criteriaTable.hideRow(row)
                self.criteriaTable.setNumRows(0)

            self.setLbAttr()

            self.criteriaTable.setCurrentCell(-1,1)
            self.boxButtons.setEnabled(True)

        else:
            self.name2var = {}
            self.varList = []
            self.Conditions = []
            self.lbAttr.clear()
            self.leSelect.clear()
            self.currentVar = None
            for row in range(self.criteriaTable.numRows()-1,-1,-1):
                self.criteriaTable.clearCellWidget(row,0)
                self.criteriaTable.clearCell(row,1)
                self.criteriaTable.hideRow(row)
            self.criteriaTable.setNumRows(0)
            self.criteriaTable.setCurrentCell(-1,1)
            self.boxButtons.setEnabled(False)
        # update operators, values and info, and send out data
        self.updateOperatorStack()
        self.updateValuesStack()
        self.updateInfoIn(self.data)
        self.setOutput()

    def setLbAttr(self, filter=None):
        # update attribute listbox
        self.lbAttr.clear()
        if not filter:
            for v in self.varList:
                self.lbAttr.insertItem(self.icons[v.varType], v.name)
        else:
            flen = len(filter)
            for v in self.varList:
                if v.name[:flen] == filter:
                    self.lbAttr.insertItem(self.icons[v.varType], v.name)

        if self.lbAttr.count():
            self.lbAttr.setSelected(0,True)
        else:
            self.lbAttrChange()


    def setOutput(self):
        """Sends out data, updates data out info.
        """
        matchingOutput = self.data
        nonMatchingOutput = None
        hasClass = False
        if self.data:
            hasClass = bool(self.data.domain.classVar)
            filterList = self.getFilterList(self.data.domain, self.Conditions, enabledOnly=True)
            if len(filterList)>0:
                filter = orange.Filter_disjunction([orange.Filter_conjunction(l) for l in filterList])
            else:
                filter = orange.Filter_conjunction([]) # a filter that does nothing
            matchingOutput = filter(self.data)
            matchingOutput.name = self.data.name
##            print "len(matchingOutput)", len(matchingOutput)
            nonMatchingOutput = filter(self.data, negate=1)
            nonMatchingOutput.name = self.data.name
##            print "len(nonMatchingOutput)", len(nonMatchingOutput)

            if self.purgeAttributes or self.purgeClasses:
                remover = orange.RemoveUnusedValues(removeOneValued=True)

                newDomain = remover(matchingOutput, 0, True, self.purgeClasses)
                if newDomain != matchingOutput.domain:
                    matchingOutput = orange.ExampleTable(newDomain, matchingOutput)
                    
                newDomain = remover(nonMatchingOutput, 0, True, self.purgeClasses)
                if newDomain != nonMatchingOutput.domain:
                    nonmatchingOutput = orange.ExampleTable(newDomain, nonMatchingOutput)

        self.send("Matching Examples", matchingOutput)
        self.send("Non-Matching Examples", nonMatchingOutput)

        if hasClass:
            self.send("Matching Classified Examples", matchingOutput)
            self.send("Non-Matching Classified Examples", nonMatchingOutput)
        else:
            self.send("Matching Classified Examples", None)
            self.send("Non-Matching Classified Examples", None)
        self.updateInfoOut(matchingOutput)


    def getFilterList(self, domain, conditions, enabledOnly):
        """Returns list of lists of orange filters, e.g. [[f1,f2],[f3]].
        OR is always enabled (with no respect to cond.enabled)
        """

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -