Changeset 10532:a447a4e8ff8a in orange for Orange/data/io.py


Ignore:
Timestamp:
03/15/12 14:46:17 (2 years ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
rebase_source:
870eb4a1ae24e1212afb313b27eb01635cbe75fd
Message:

Bug fixes, can now handle missing values, other small improvements.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • Orange/data/io.py

    r10528 r10532  
    531531            specifier = "class" 
    532532            items = items[1:] 
     533        elif items[0] == "multiclass": 
     534            specifier = "multiclass" 
     535            items = items[1:] 
     536        elif items[0] in ["i", "ignore"]: 
     537            specifier = "ignore" 
     538            items = items[1:] 
    533539        return specifier, dict(map(_var_attribute_label_parse, items)) 
    534540    else: 
     
    536542 
    537543def var_attributes(row): 
    538     """ Return variable specifiers and label definitions for row 
     544    """ Return variable specifiers and label definitions for row. 
    539545    """ 
    540546    return map(var_attribute, row) 
     
    583589def load_csv(file, create_new_on=MakeStatus.Incompatible,  
    584590             delimiter=None, quotechar=None, escapechar=None, 
    585              has_header=None, has_types=None, has_annotations=None, **kwargs): 
     591             skipinitialspace=None, has_header=None,  
     592             has_types=None, has_annotations=None, DK=None, **kwargs): 
    586593    """ Load an Orange.data.Table from s csv file. 
    587594    """ 
     
    604611    fmtparam = kwparams(delimiter=delimiter, 
    605612                        quotechar=quotechar, 
    606                         escapechar=escapechar) 
     613                        escapechar=escapechar, 
     614                        skipinitialspace=skipinitialspace) 
    607615     
    608616    reader = csv.reader(file, dialect=dialect, 
     
    661669    variables = [] 
    662670    undefined_vars = [] 
     671    # Missing value flags  
     672    missing_flags = DK.split(",") if DK is not None else ["?", "", "NA", "~", "*"] 
     673    missing_map = dict.fromkeys(missing_flags, "?") 
     674    missing_translate = lambda val: missing_map.get(val, val) 
     675        
     676    # Create domain variables or corresponding place holders 
    663677    for i, (name, var_t) in enumerate(zip(header, types)): 
    664         if var_t == variable.Discrete:# We do not have values yet. 
     678        if var_t == variable.Discrete: 
     679            # We do not have values yet 
    665680            variables.append(_disc_placeholder(name)) 
    666681            undefined_vars.append((i, variables[-1])) 
     
    674689            var_t, values = var_t 
    675690            if var_t == variable.Discrete: 
     691                # We have values for discrete variable 
    676692                variables.append(make(name, Orange.feature.Type.Discrete, values, [], create_new_on)) 
    677693            elif var_t == variable.Python: 
     694                # Python variables are not supported yet 
    678695                raise NotImplementedError() 
    679696        elif var_t is None: 
     697            # Unknown variable type, to be deduced at the end 
    680698            variables.append(_var_placeholder(name)) 
    681699            undefined_vars.append((i, variables[-1])) 
    682700 
    683701    data = [] 
     702    # Read all the rows 
    684703    for row in reader: 
    685         data.append(row) 
    686         for ind, var_def in undefined_vars: 
    687             var_def.values.add(row[ind]) 
    688  
     704        # check for final newline. 
     705        if row: 
     706            row = map(missing_translate, row) 
     707            data.append(row) 
     708            # For undefined variables collect all their values 
     709            for ind, var_def in undefined_vars: 
     710                var_def.values.add(row[ind]) 
     711     
     712    # Process undefined variables now that we can deduce their type  
    689713    for ind, var_def in undefined_vars: 
    690714        values = var_def.values - set(["?", ""]) # TODO: Other unknown strings? 
     
    702726                raise ValueError("Strange column in the data") 
    703727 
    704     vars = [] 
    705     vars_load_status = [] 
    706728    attribute_load_status = [] 
    707729    meta_attribute_load_status = {} 
    708730    class_var_load_status = [] 
    709     for var, status in vars: 
    710         vars.append(var) 
    711         vars_load_status.append(status) 
     731    multiclass_var_load_status = [] 
    712732 
    713733    attributes = [] 
    714734    class_var = [] 
     735    class_vars = [] 
    715736    metas = {} 
    716737    attribute_indices = [] 
    717738    variable_indices = [] 
    718739    class_indices = [] 
     740    multiclass_indices = [] 
    719741    meta_indices = [] 
     742    ignore_indices = [] 
    720743    for i, ((var, status), var_attr) in enumerate(zip(variables, var_attrs)): 
    721744        if var_attr: 
     
    725748                class_var_load_status.append(status) 
    726749                class_indices.append(i) 
     750            elif flag == "multiclass": 
     751                class_vars.append(var) 
     752                multiclass_var_load_status.append(status) 
     753                multiclass_indices.append(i) 
    727754            elif flag == "meta": 
    728755                mid = Orange.feature.Descriptor.new_meta_id() 
     
    730757                meta_attribute_load_status[mid] = status 
    731758                meta_indices.append((i, var)) 
     759            elif flag == "ignore": 
     760                ignore_indices.append(i) 
    732761            else: 
    733762                attributes.append(var) 
     
    742771    if len(class_var) > 1: 
    743772        raise ValueError("Multiple class variables defined") 
     773    if class_var and class_vars: 
     774        raise ValueError("Both 'class' and 'multiclass' used.") 
    744775 
    745776    class_var = class_var[0] if class_var else None 
    746  
     777     
    747778    attribute_load_status += class_var_load_status 
    748779    variable_indices = attribute_indices + class_indices 
    749     domain = Orange.data.Domain(attributes, class_var) 
     780    domain = Orange.data.Domain(attributes, class_var, class_vars=class_vars) 
    750781    domain.add_metas(metas) 
    751782    normal = [[row[i] for i in variable_indices] for row in data] 
    752783    meta_part = [[row[i] for i, _ in meta_indices] for row in data] 
     784    multiclass_part = [[row[i] for i in multiclass_indices] for row in data] 
    753785    table = Orange.data.Table(domain, normal) 
    754     for ex, m_part in zip(table, meta_part): 
     786    for ex, m_part, mc_part in zip(table, meta_part, multiclass_part): 
    755787        for (column, var), val in zip(meta_indices, m_part): 
    756788            ex[var] = var(val) 
     789        if mc_part: 
     790            ex.set_classes(mc_part) 
    757791 
    758792    table.setattr("metaAttributeLoadStatus", meta_attribute_load_status) 
Note: See TracChangeset for help on using the changeset viewer.