source: orange/Orange/OrangeWidgets/Data/OWPurgeDomain.py @ 11748:467f952c108d

Revision 11748:467f952c108d, 8.4 KB checked in by blaz <blaz.zupan@…>, 6 months ago (diff)

Changes in headers, widget descriptions text.

Line 
1from OWWidget import *
2import OWGUI
3
4import orange
5
6NAME = "Purge Domain"
7DESCRIPTION = "Removes redundant values and features, sorts domain values."
8LONG_DESCRIPTION = ""
9ICON = "icons/PurgeDomain.svg"
10PRIORITY = 1150
11AUTHOR = "Janez Demsar"
12AUTHOR_EMAIL = "janez.demsar(@at@)fri.uni-lj.si"
13INPUTS = [("Data", Orange.data.Table, "setData")]
14OUTPUTS = [("Data", Orange.data.Table)]
15
16
17class OWPurgeDomain(OWWidget):
18
19    def __init__(self, parent=None, signalManager=None):
20        OWWidget.__init__(self, parent, signalManager, 'PurgeDomain', wantMainArea=False)
21        self.settingsList=["removeValues", "removeAttributes", "removeClassAttribute", "removeClasses", "autoSend", "sortValues", "sortClasses"]
22
23        self.inputs = [("Data", ExampleTable, self.setData)]
24        self.outputs = [("Data", ExampleTable)]
25
26        self.data = None
27
28        self.preRemoveValues = self.removeValues = 1
29        self.removeAttributes = 1
30        self.removeClassAttribute = 1
31        self.preRemoveClasses = self.removeClasses = 1
32        self.autoSend = 1
33        self.dataChanged = False
34
35        self.sortValues = self.sortClasses = True
36
37        self.loadSettings()
38
39        self.removedAttrs = self.reducedAttrs = self.resortedAttrs = self.classAttr = "-"
40
41        boxAt = OWGUI.widgetBox(self.controlArea, "Attributes", addSpace=True)
42        OWGUI.checkBox(boxAt, self, 'sortValues', 'Sort attribute values', callback = self.optionsChanged)
43        rua = OWGUI.checkBox(boxAt, self, "removeAttributes", "Remove attributes with less than two values", callback = self.removeAttributesChanged)
44
45        ruv = OWGUI.checkBox(OWGUI.indentedBox(boxAt, sep=OWGUI.checkButtonOffsetHint(rua)), self, "removeValues", "Remove unused attribute values", callback = self.optionsChanged)
46        rua.disables = [ruv]
47        rua.makeConsistent()
48
49
50        boxAt = OWGUI.widgetBox(self.controlArea, "Classes", addSpace=True)
51        OWGUI.checkBox(boxAt, self, 'sortClasses', 'Sort classes', callback = self.optionsChanged)
52        rua = OWGUI.checkBox(boxAt, self, "removeClassAttribute", "Remove class attribute if there are less than two classes", callback = self.removeClassesChanged)
53        ruv = OWGUI.checkBox(OWGUI.indentedBox(boxAt, sep=OWGUI.checkButtonOffsetHint(rua)), self, "removeClasses", "Remove unused class values", callback = self.optionsChanged)
54        rua.disables = [ruv]
55        rua.makeConsistent()
56
57
58        box3 = OWGUI.widgetBox(self.controlArea, 'Statistics', addSpace=True)
59        OWGUI.label(box3, self, "Removed attributes: %(removedAttrs)s")
60        OWGUI.label(box3, self, "Reduced attributes: %(reducedAttrs)s")
61        OWGUI.label(box3, self, "Resorted attributes: %(resortedAttrs)s")
62        OWGUI.label(box3, self, "Class attribute: %(classAttr)s")
63       
64        box2 = OWGUI.widgetBox(self.controlArea, "Send")
65        btSend = OWGUI.button(box2, self, "Send data", callback = self.process, default=True)
66        cbAutoSend = OWGUI.checkBox(box2, self, "autoSend", "Send automatically")
67
68        OWGUI.setStopper(self, btSend, cbAutoSend, "dataChanged", self.process)
69       
70        OWGUI.rubber(self.controlArea)
71
72#        OWGUI.separator(self.controlArea, height=24)
73
74        #self.adjustSize()
75
76    def setData(self, dataset):
77        if dataset:
78            self.data = dataset
79            self.process()
80        else:
81            self.reducedAttrs = self.removedAttrs = self.resortedAttrs = self.classAttr = ""
82            self.send("Data", None)
83            self.data = None
84        self.dataChanged = False
85
86    def removeAttributesChanged(self):
87        if not self.removeAttributes:
88            self.preRemoveValues = self.removeValues
89            self.removeValues = False
90        else:
91            self.removeValues = self.preRemoveValues
92        self.optionsChanged()
93
94    def removeClassesChanged(self):
95        if not self.removeClassAttribute:
96            self.preRemoveClasses = self.removeClasses
97            self.removeClasses = False
98        else:
99            self.removeClasses = self.preRemoveClasses
100        self.optionsChanged()
101
102    def optionsChanged(self):
103        if self.autoSend:
104            self.process()
105        else:
106            self.dataChanged = True
107
108    def sortAttrValues(self, attr, interattr=None):
109        if not interattr:
110            interattr = attr
111
112        newvalues = list(interattr.values)
113        newvalues.sort()
114        if newvalues == list(interattr.values):
115            return interattr
116
117        newattr = orange.EnumVariable(interattr.name, values=newvalues)
118        newattr.getValueFrom = orange.ClassifierByLookupTable(newattr, attr)
119        lookupTable = newattr.getValueFrom.lookupTable
120        distributions = newattr.getValueFrom.distributions
121        for val in interattr.values:
122            idx = attr.values.index(val)
123            lookupTable[idx] = val
124            distributions[idx][newvalues.index(val)] += 1
125        return newattr
126
127    def process(self):
128        if self.data == None:
129            return
130
131        self.reducedAttrs = 0
132        self.removedAttrs = 0
133        self.resortedAttrs = 0
134        self.classAttribute = 0
135
136        if self.removeAttributes or self.sortValues:
137            newattrs = []
138            for attr in self.data.domain.attributes:
139                if attr.varType == orange.VarTypes.Continuous:
140                    if orange.RemoveRedundantOneValue.has_at_least_two_values(self.data, attr):
141                        newattrs.append(attr)
142                    else:
143                        self.removedAttrs += 1
144                    continue
145
146                if attr.varType != orange.VarTypes.Discrete:
147                    newattrs.append(attr)
148                    continue
149
150                if self.removeValues:
151                    newattr = orange.RemoveUnusedValues(attr, self.data)
152                    if not newattr:
153                        self.removedAttrs += 1
154                        continue
155
156                    if newattr != attr:
157                        self.reducedAttrs += 1
158                else:
159                    newattr = attr
160
161                if self.removeValues and len(newattr.values) < 2:
162                    self.removedAttrs += 1
163                    continue
164
165                if self.sortValues:
166                    newnewattr = self.sortAttrValues(attr, newattr)
167                    if newnewattr != newattr:
168                        self.resortedAttrs += 1
169                        newattr = newnewattr
170
171                newattrs.append(newattr)
172        else:
173            newattrs = self.data.domain.attributes
174
175
176        klass = self.data.domain.classVar
177        classChanged = False
178        if not klass:
179            newclass = klass
180            self.classAttr = "No class"
181        elif klass.varType != orange.VarTypes.Discrete:
182            newclass = klass
183            self.classAttr = "Class is not discrete"
184        elif not (self.removeClassAttribute or self.sortClasses):
185            newclass = klass
186            self.classAttr = "Class is not checked"
187        else:
188            self.classAttr = ""
189
190            if self.removeClasses:
191                newclass = orange.RemoveUnusedValues(klass, self.data)
192            else:
193                newclass = klass
194
195            if not newclass or self.removeClassAttribute and len(newclass.values) < 2:
196                newclass = None
197                self.classAttr = "Class is removed"
198            elif len(newclass.values) != len(klass.values):
199                    self.classAttr = "Class is reduced"
200
201            if newclass and self.sortClasses:
202                newnewclass = self.sortAttrValues(klass, newclass)
203                if newnewclass != newclass:
204                    if self.classAttr:
205                        self.classAttr = "Class is reduced and sorted"
206                    else:
207                        self.classAttr = "Class is sorted"
208                    newclass = newnewclass
209
210            if not self.classAttr:
211                self.classAttr = "Class is unchanged"
212
213        if self.reducedAttrs or self.removedAttrs or self.resortedAttrs or newclass != klass:
214            newDomain = orange.Domain(newattrs, newclass)
215            newData = orange.ExampleTable(newDomain, self.data)
216        else:
217            newData = self.data
218
219        self.send("Data", newData)
220
221        self.dataChanged = False
222
223
224if __name__=="__main__":
225    appl = QApplication(sys.argv)
226    ow = OWPurgeDomain()
227    #data = orange.ExampleTable('..\\..\\doc\\datasets\\car.tab')
228    #data.domain.attributes[3].values.append("X")
229    #ow.setData(data)
230    ow.show()
231    appl.exec_()
232    ow.saveSettings()
Note: See TracBrowser for help on using the repository browser.