Changeset 7933:a1a46faeb90a in orange


Ignore:
Timestamp:
05/25/11 11:03:49 (3 years ago)
Author:
anze <anze.staric@…>
Branch:
default
Convert:
71f65757c96da5c74af293b3303dc3d3bf91f8e3
Message:

Moved code from orngIO to Orange.data.io. Added regression test for reading and writing Weka ARFF format.

Location:
orange
Files:
3 added
1 edited

Legend:

Unmodified
Added
Removed
  • orange/Orange/data/io.py

    r6848 r7933  
    11from orange import \ 
    22     BasketFeeder, FileExampleGenerator, BasketExampleGenerator, \ 
    3      C45ExampleGenerator, TabDelimExampleGenerator 
     3     C45ExampleGenerator, TabDelimExampleGenerator, registerFileType 
     4 
     5import Orange.data.variable 
     6import os 
     7 
     8def loadARFF(filename, create_on_new = Orange.data.variable.Variable.MakeStatus.Incompatible, **kwargs): 
     9    """Return class:`Orange.data.Table` containing data from file filename""" 
     10    if not os.path.exists(filename) and os.path.exists(filename + ".arff"): 
     11        filename = filename + ".arff"  
     12    f = open(filename,'r') 
     13     
     14    attributes = [] 
     15    attributeLoadStatus = [] 
     16     
     17    name = '' 
     18    state = 0 # header 
     19    data = [] 
     20    for l in f.readlines(): 
     21        l = l.rstrip("\n") # strip \n 
     22        l = l.replace('\t',' ') # get rid of tabs 
     23        x = l.split('%')[0] # strip comments 
     24        if len(x.strip()) == 0: 
     25            continue 
     26        if state == 0 and x[0] != '@': 
     27            print "ARFF import ignoring:",x 
     28        if state == 1: 
     29            dd = x.split(',') 
     30            r = [] 
     31            for xs in dd: 
     32                y = xs.strip(" ") 
     33                if len(y) > 0: 
     34                    if y[0]=="'" or y[0]=='"': 
     35                        r.append(xs.strip("'\"")) 
     36                    else: 
     37                        ns = xs.split() 
     38                        for ls in ns: 
     39                            if len(ls) > 0: 
     40                                r.append(ls) 
     41                else: 
     42                    r.append('?') 
     43            data.append(r[:len(attributes)]) 
     44        else: 
     45            y = [] 
     46            for cy in x.split(' '): 
     47                if len(cy) > 0: 
     48                    y.append(cy) 
     49            if str.lower(y[0][1:]) == 'data': 
     50                state = 1 
     51            elif str.lower(y[0][1:]) == 'relation': 
     52                name = str.strip(y[1]) 
     53            elif str.lower(y[0][1:]) == 'attribute': 
     54                if y[1][0] == "'": 
     55                    atn = y[1].strip("' ") 
     56                    idx = 1 
     57                    while y[idx][-1] != "'": 
     58                        idx += 1 
     59                        atn += ' '+y[idx] 
     60                    atn = atn.strip("' ") 
     61                else: 
     62                    atn = y[1] 
     63                z = x.split('{') 
     64                w = z[-1].split('}') 
     65                if len(z) > 1 and len(w) > 1: 
     66                    # there is a list of values 
     67                    vals = [] 
     68                    for y in w[0].split(','): 
     69                        sy = y.strip(" '\"") 
     70                        if len(sy)>0: 
     71                            vals.append(sy) 
     72                    a, s = Orange.data.variable.Variable.make(atn, Orange.data.Type.Discrete, vals, [], create_on_new) 
     73                else: 
     74                    # real... 
     75                    a, s = Orange.data.variable.Variable.make(atn, Orange.data.Type.Continuous, [], [], create_on_new) 
     76                     
     77                attributes.append(a) 
     78                attributeLoadStatus.append(s) 
     79    # generate the domain 
     80    d = Orange.data.Domain(attributes) 
     81    lex = [] 
     82    for dd in data: 
     83        e = Orange.data.Instance(d,dd) 
     84        lex.append(e) 
     85    t = Orange.data.Table(d,lex) 
     86    t.name = name 
     87    t.attribute_load_status = attributeLoadStatus 
     88    return t 
     89 
     90def toARFF(filename,table,try_numericize=0): 
     91    """Save class:`Orange.data.Table` to file filename in ARFF format""" 
     92    t = table 
     93    if filename[-5:] == ".arff": 
     94        filename = filename[:-5] 
     95    #print filename 
     96    f = open(filename+'.arff','w') 
     97    f.write('@relation %s\n'%t.domain.classVar.name) 
     98    # attributes 
     99    ats = [i for i in t.domain.attributes] 
     100    ats.append(t.domain.classVar) 
     101    for i in ats: 
     102        real = 1 
     103        if i.varType == 1: 
     104            if try_numericize: 
     105                # try if all values numeric 
     106                for j in i.values: 
     107                    try: 
     108                        x = float(j) 
     109                    except: 
     110                        real = 0 # failed 
     111                        break 
     112            else: 
     113                real = 0 
     114        iname = str(i.name) 
     115        if iname.find(" ") != -1: 
     116            iname = "'%s'"%iname 
     117        if real==1: 
     118            f.write('@attribute %s real\n'%iname) 
     119        else: 
     120            f.write('@attribute %s { '%iname) 
     121            x = [] 
     122            for j in i.values: 
     123                s = str(j) 
     124                if s.find(" ") == -1: 
     125                    x.append("%s"%s) 
     126                else: 
     127                    x.append("'%s'"%s) 
     128            for j in x[:-1]: 
     129                f.write('%s,'%j) 
     130            f.write('%s }\n'%x[-1]) 
     131 
     132    # examples 
     133    f.write('@data\n') 
     134    for j in t: 
     135        x = [] 
     136        for i in range(len(ats)): 
     137            s = str(j[i]) 
     138            if s.find(" ") == -1: 
     139                x.append("%s"%s) 
     140            else: 
     141                x.append("'%s'"%s) 
     142        for i in x[:-1]: 
     143            f.write('%s,'%i) 
     144        f.write('%s\n'%x[-1]) 
     145 
     146def toC50(filename,table): 
     147    t = table 
     148    # export names 
     149    f = open('%s.names' % filename,'w') 
     150    f.write('%s.\n\n' % t.domain.class_var.name) 
     151    # attributes 
     152    ats = [i for i in t.domain.attributes] 
     153    ats.append(t.domain.classVar) 
     154    for i in ats: 
     155        real = 1 
     156        # try if real 
     157        if i.varType == 1 and try_numericize: 
     158            # try if all values numeric 
     159            for j in i.values: 
     160                try: 
     161                    x = float(j) 
     162                except: 
     163                    real = 0 # failed 
     164                    break 
     165        if real==1: 
     166            f.write('%s: continuous.\n'%i.name) 
     167        else: 
     168            f.write('%s: '%i.name) 
     169            x = [] 
     170            for j in i.values: 
     171                x.append('%s'%j) 
     172            for j in x[:-1]: 
     173                f.write('%s,'%j) 
     174            f.write('%s.\n'%x[-1]) 
     175    # examples 
     176    f.close() 
     177     
     178    f = open('%s.data'%n,'w') 
     179    for j in t: 
     180        x = [] 
     181        for i in range(len(ats)): 
     182            x.append('%s'%j[i]) 
     183        for i in x[:-1]: 
     184            f.write('%s,'%i) 
     185        f.write('%s\n'%x[-1]) 
     186 
     187def toR(filename,t): 
     188    if str.upper(filename[-2:]) == ".R": 
     189        filename = filename[:-2] 
     190    f = open(filename+'.R','w') 
     191 
     192    atyp = [] 
     193    aord = [] 
     194    labels = [] 
     195    as0 = [] 
     196    for a in t.domain.attributes: 
     197        as0.append(a) 
     198    as0.append(t.domain.class_var) 
     199    for a in as0: 
     200        labels.append(str(a.name)) 
     201        atyp.append(a.var_ype) 
     202        aord.append(a.ordered) 
     203 
     204    f.write('data <- data.frame(\n') 
     205    for i in xrange(len(labels)): 
     206        if atyp[i] == 2: # continuous 
     207            f.write('"%s" = c('%(labels[i])) 
     208            for j in xrange(len(t)): 
     209                if t[j][i].isSpecial(): 
     210                    f.write('NA') 
     211                else: 
     212                    f.write(str(t[j][i])) 
     213                if (j == len(t)-1): 
     214                    f.write(')') 
     215                else: 
     216                    f.write(',') 
     217        elif atyp[i] == 1: # discrete 
     218            if aord[i]: # ordered 
     219                f.write('"%s" = ordered('%labels[i]) 
     220            else: 
     221                f.write('"%s" = factor('%labels[i]) 
     222            f.write('levels=c(') 
     223            for j in xrange(len(as0[i].values)): 
     224                f.write('"x%s"'%(as0[i].values[j])) 
     225                if j == len(as0[i].values)-1: 
     226                    f.write('),c(') 
     227                else: 
     228                    f.write(',') 
     229            for j in xrange(len(t)): 
     230                if t[j][i].isSpecial(): 
     231                    f.write('NA') 
     232                else: 
     233                    f.write('"x%s"'%str(t[j][i])) 
     234                if (j == len(t)-1): 
     235                    f.write('))') 
     236                else: 
     237                    f.write(',') 
     238        else: 
     239            raise "Unknown attribute type." 
     240        if (i < len(labels)-1): 
     241            f.write(',\n') 
     242    f.write(')\n') 
     243     
     244def toLibSVM(filename, example): 
     245    import Orange.classification.svm 
     246    Orange.classification.svm.tableToSVMFormat(example, open(filename, "wb")) 
     247     
     248def loadLibSVM(filename, create_on_new=Orange.data.variable.Variable.MakeStatus.Incompatible, **kwargs): 
     249    attributeLoadStatus = {} 
     250    def make_float(name): 
     251        attr, s = orange.Variable.make(name, orange.VarTypes.Continuous, [], [], createOnNew) 
     252        attributeLoadStatus[attr] = s 
     253        return attr 
     254     
     255    def make_disc(name, unordered): 
     256        attr, s = orange.Variable.make(name, orange.VarTypes.Discrete, [], unordered, createOnNew) 
     257        attributeLoadStatus[attr] = s 
     258        return attr 
     259     
     260    data = [line.split() for line in open(filename, "rb").read().splitlines() if line.strip()] 
     261    vars = type("attr", (dict,), {"__missing__": lambda self, key: self.setdefault(key, make_float(key))})() 
     262    item = lambda i, v: (vars[i], vars[i](v)) 
     263    values = [dict([item(*val.split(":"))  for val in ex[1:]]) for ex in data] 
     264    classes = [ex[0] for ex in data] 
     265    disc = all(["." not in c for c in classes]) 
     266    attributes = sorted(vars.values(), key=lambda var: int(var.name)) 
     267    classVar = make_disc("class", sorted(set(classes))) if disc else make_float("target") 
     268    attributeLoadStatus = [attributeLoadStatus[attr] for attr in attributes] + \ 
     269                          [attributeLoadStatus[classVar]] 
     270    domain = orange.Domain(attributes, classVar) 
     271    table = orange.ExampleTable([orange.Example(domain, [ex.get(attr, attr("?")) for attr in attributes] + [c]) for ex, c in zip(values, classes)]) 
     272    table.attribute_load_status = attributeLoadStatus 
     273    return table 
     274 
     275registerFileType("R", None, toR, ".R") 
     276registerFileType("Weka", loadARFF, toARFF, ".arff") 
     277registerFileType("C50", None, toC50, [".names", ".data", ".test"]) 
     278registerFileType("libSVM", loadLibSVM, toLibSVM, ".svm") 
Note: See TracChangeset for help on using the changeset viewer.