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

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

Changes in headers, widget descriptions text.

RevLine 
[11748]1import Orange
[8042]2from OWWidget import *
3import OWGUI
4from itertools import izip
5
[11748]6NAME = "Concatenate"
7DESCRIPTION = "Concatenates data tables."
8ICON = "icons/Concatenate.svg"
9PRIORITY = 1111
10MAINTAINER = "Janez Demsar"
11MAINTAINER_EMAIL = "janez.demsar(@at@)fri.uni-lj.si"
12INPUTS = [("Primary Data", Orange.data.Table, "setData"),
13          ("Additional Data", Orange.data.Table, "setMoreData", Multiple)]
14OUTPUTS = [("Data", Orange.data.Table, )]
15
16
[8042]17class OWConcatenate(OWWidget):
18    settingsList = ["mergeAttributes", "dataSourceSelected", "addIdAs", "dataSourceName"]
19   
20    def __init__(self,parent=None, signalManager = None):
21        OWWidget.__init__(self, parent, signalManager, "Concatenate", wantMainArea=0)
[11748]22        self.inputs = [("Primary Data", orange.ExampleTable, self.setData),
23                       ("Additional Data", orange.ExampleTable, self.setMoreData, Multiple)]
[9546]24        self.outputs = [("Data", ExampleTable)]
[8042]25
26        self.mergeAttributes = 0
27        self.dataSourceSelected = 1
28        self.addIdAs = 0
29        self.dataSourceName = "clusterId"
30
31        self.primary = None
32        self.additional = {}
33       
34        self.loadSettings()
35       
36        bg = self.bgMerge = OWGUI.radioButtonsInBox(self.controlArea, self, "mergeAttributes", [], "Domains merging", callback = self.apply)
37        OWGUI.widgetLabel(bg, "When there is no primary table, the domain should be")
38        OWGUI.appendRadioButton(bg, self, "mergeAttributes", "Union of attributes appearing in all tables")
39        OWGUI.appendRadioButton(bg, self, "mergeAttributes", "Intersection of attributes in all tables")
40        OWGUI.widgetLabel(bg, "The resulting table will have class only if there is no conflict between input classes.")
41
42        OWGUI.separator(self.controlArea)
43        box = OWGUI.widgetBox(self.controlArea, "Data source IDs", addSpace=True)
44        cb = OWGUI.checkBox(box, self, "dataSourceSelected", "Append data source IDs")
45        self.classificationBox = ib = OWGUI.indentedBox(box, sep=OWGUI.checkButtonOffsetHint(cb))
46        le = OWGUI.lineEdit(ib, self, "dataSourceName", "Name" + "  ", orientation='horizontal', valueType = str)
47        OWGUI.separator(ib, height = 4)
48        aa = OWGUI.comboBox(ib, self, "addIdAs", label = "Place" + "  ", orientation = 'horizontal', items = ["Class attribute", "Attribute", "Meta attribute"])
49        cb.disables.append(ib)
50        cb.makeConsistent()
51       
52        OWGUI.button(self.controlArea, self, "Apply Changes", callback = self.apply, default=True)
53       
54        OWGUI.rubber(self.controlArea)
55
56        self.adjustSize()
[9271]57       
58        self.dataReport = None
[8042]59
60
61    def setData(self, data):
62        self.primary = data
63        self.bgMerge.setEnabled(not data)
64        self.apply()
65       
66
67    def setMoreData(self, data, id):
68        if not data:
69            if id in self.additional:
70                del self.additional[id]
71        else:
72            self.additional[id] = data
73        self.apply()
74       
75   
76    def apply(self):
77        dataSourceIDs = []
78        currentID = 1
79       
80        if self.primary:
81            if not self.additional:
82                newTable = self.primary
83                dataSourceIDs.extend([currentID] * len(self.primary))
84                currentID += 1
85            else:
86                newTable = orange.ExampleTable(self.primary)
87                dataSourceIDs.extend([currentID] * len(self.primary))
88                currentID += 1
89               
90                for additional in self.additional.values():
91                    newTable.extend(additional)
92                    dataSourceIDs.extend([currentID] * len(additional))
93                    currentID += 1
94
95        else:
96            if not self.additional:
97                newTable = None
98               
99            else:
100                classVar = False
101                for additional in self.additional.values():
102                    if additional.domain.classVar:
103                        if classVar == False: # can also be None
104                            classVar = additional.domain.classVar
105                        elif classVar != additional.domain.classVar:
106                            classVar = None
107                           
108                if self.mergeAttributes: # intersection
109                    attributes = metas = None
110                    for additional in self.additional.values():
111                        if attributes == None:
112                            if classVar:
113                                attributes = additional.domain.attributes
114                            else:
115                                attributes = additional.domain
116                            metas = dict((attr, id) for id, attr in additional.domain.getmetas().items())
117                        else:
118                            attributes = [attr for attr in attributes if attr in additional.domain and not attr == classVar]
119                            metas = dict((attr, id) for id, attr in additional.domain.getmetas().items() if attr in metas)
120                    if attributes == None:
121                        attributes = []
122                        metas = {}
123                else: # union
124                    attributes = []
125                    metas = {}
126                    for additional in self.additional.values():
127                        for attr in additional.domain:
128                            if attr not in attributes and attr != classVar:
129                                attributes.append(attr)
130                        for id, attr in additional.domain.getmetas().items():
131                            if not attr in metas:
132                                metas[attr] = id
133                if not attributes and not classVar:
134                    self.error(1, "The output domain is empty.")
135                    newTable = None
136                else:
137                    self.error(1)
138                    newDomain = orange.Domain(attributes, classVar)
139                    newDomain.addmetas(dict((x[1], x[0]) for x in metas.items())) 
140                    newTable = orange.ExampleTable(newDomain)
141                    for additional in self.additional.values():
142                        newTable.extend(additional)
143                        dataSourceIDs.extend([currentID] * len(additional))
144                        currentID += 1
145       
146        if newTable != None:
147            tableCount = 0
148            if self.primary:
149                tableCount += 1
150            if self.additional:
151                tableCount += len(self.additional)
152           
153            origDomain = newTable.domain
154            if self.dataSourceSelected:
155                dataSourceVar = orange.EnumVariable(self.dataSourceName, values = [str(x) for x in range(1, 1 + tableCount)])
156                if self.addIdAs == 0:
157                    domain = orange.Domain(origDomain.attributes, dataSourceVar)
158                    if origDomain.classVar:
159                        domain.addmeta(orange.newmetaid(), origDomain.classVar)
160                    aid = -1
161                elif self.addIdAs == 1:
162                    domain=orange.Domain(origDomain.attributes+[dataSourceVar], origDomain.classVar)
163                    aid = len(origDomain.attributes)
164                else:
165                    domain=orange.Domain(origDomain.attributes, origDomain.classVar)
166                    aid=orange.newmetaid()
167                    domain.addmeta(aid, dataSourceVar)
168            else:
169                domain = orange.Domain(origDomain.attributes, origDomain.classVar)
170
171            domain.addmetas(origDomain.getmetas())
172           
173            table1 = orange.ExampleTable(domain)
174            table1.extend(newTable)
175           
176            if self.dataSourceSelected:
177                for ex, id in izip(table1, dataSourceIDs):
178                    ex[aid] = dataSourceVar(str(id))
179
180            newTable = table1
181
182        self.dataReport = self.prepareDataReport(newTable)
[9546]183        self.send("Data", newTable)
[8042]184
185    def sendReport(self):
186        self.reportData(self.primary, "Primary table", 
187                        "None; outputting the %s of attributes from all tables" % ["union", "intersection"][self.mergeAttributes]) 
188        for additional in self.additional.values():
189            self.reportData(additional, "Additional table")
190        if not self.additional:
191            self.reportData(None, "Additional table")
192        self.reportData(self.dataReport, "Merged data")
193       
194if __name__ == "__main__":
195    app = QApplication(sys.argv)
196    w = OWConcatenate()
[11748]197    data = Orange.data.Table("iris.tab")
[8042]198    w.setData(data)
199    w.setMoreData(data, 0)
200    w.show()
201    app.exec_()
202
Note: See TracBrowser for help on using the repository browser.