Skip to content

Commit

Permalink
Merge pull request biolab#1822 from nikicc/save-sparse-data
Browse files Browse the repository at this point in the history
OWSave: Offer Only Supported Writers for Sparse Data
(cherry picked from commit c29c7e6)
  • Loading branch information
lanzagar authored and astaric committed Jan 18, 2017
1 parent 97a7a8d commit 1978481
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 6 deletions.
6 changes: 6 additions & 0 deletions Orange/data/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ class FileFormat(metaclass=FileFormatMeta):
EXTENSIONS = ('.ext1', '.ext2', ...)
DESCRIPTION = 'human-readable file format description'
SUPPORT_COMPRESSED = False
SUPPORT_SPARSE_DATA = False
def read(self):
... # load headers, data, ...
Expand Down Expand Up @@ -681,6 +682,7 @@ class CSVReader(FileFormat):
DESCRIPTION = 'Comma-separated values'
DELIMITERS = ',;:\t$ '
SUPPORT_COMPRESSED = True
SUPPORT_SPARSE_DATA = False
PRIORITY = 20

def read(self):
Expand Down Expand Up @@ -755,6 +757,7 @@ class PickleReader(FileFormat):
"""Reader for pickled Table objects"""
EXTENSIONS = ('.pickle', '.pkl')
DESCRIPTION = 'Pickled Python object file'
SUPPORT_SPARSE_DATA = True

def read(self):
with open(self.filename, 'rb') as f:
Expand All @@ -770,6 +773,7 @@ class BasketReader(FileFormat):
"""Reader for basket (sparse) files"""
EXTENSIONS = ('.basket', '.bsk')
DESCRIPTION = 'Basket file'
SUPPORT_SPARSE_DATA = True

def read(self):
def constr_vars(inds):
Expand All @@ -794,6 +798,7 @@ class ExcelReader(FileFormat):
"""Reader for excel files"""
EXTENSIONS = ('.xls', '.xlsx')
DESCRIPTION = 'Mircosoft Excel spreadsheet'
SUPPORT_SPARSE_DATA = False

def __init__(self, filename):
super().__init__(filename)
Expand Down Expand Up @@ -835,6 +840,7 @@ class DotReader(FileFormat):
EXTENSIONS = ('.dot', '.gv')
DESCRIPTION = 'Dot graph description'
SUPPORT_COMPRESSED = True
SUPPORT_SPARSE_DATA = False

@classmethod
def write_graph(cls, filename, graph):
Expand Down
6 changes: 6 additions & 0 deletions Orange/data/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,12 @@ def is_copy(self):
(self.metas.base is None) and
(self.W.base is None))

def is_sparse(self):
"""
Return `True` if the table stores data in sparse format
"""
return any(sp.issparse(i) for i in [self.X, self.Y, self.metas])

def ensure_copy(self):
"""
Ensure that the table owns its data; copy arrays when necessary.
Expand Down
7 changes: 7 additions & 0 deletions Orange/tests/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,13 @@ def test_attributes(self):

# TODO Test conjunctions and disjunctions of conditions

def test_is_sparse(self):
table = data.Table("iris")
self.assertFalse(table.is_sparse())

table.X = sp.csr_matrix(table.X)
self.assertTrue(table.is_sparse())


def column_sizes(table):
return (len(table.domain.attributes),
Expand Down
11 changes: 5 additions & 6 deletions Orange/widgets/data/owsave.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os.path
from operator import attrgetter

from Orange.data.table import Table
from Orange.widgets import gui, widget
Expand All @@ -24,10 +23,9 @@ class OWSave(widget.OWWidget):
last_filter = Setting("")
auto_save = Setting(False)

formats = [(f.DESCRIPTION, f.EXTENSIONS)
for f in sorted(set(FileFormat.writers.values()),
key=attrgetter("PRIORITY"))]
filters = ['{} (*{})'.format(x[0], ' *'.join(x[1])) for x in formats]
writers = FileFormat.writers
sparse_writers = {ext: w for ext, w in FileFormat.writers.items()
if w.SUPPORT_SPARSE_DATA}

def __init__(self):
super().__init__()
Expand Down Expand Up @@ -63,7 +61,8 @@ def save_file_as(self):
os.path.join(self.last_dir or os.path.expanduser("~"),
getattr(self.data, 'name', ''))
filename, writer, filter = filedialogs.get_file_name(
file_name, self.last_filter, FileFormat.writers)
file_name, self.last_filter,
self.sparse_writers if self.data.is_sparse() else self.writers)
if not filename:
return
self.filename = filename
Expand Down

0 comments on commit 1978481

Please sign in to comment.