Skip to content

Commit 0c7af11

Browse files
committed
fixed #640: added possibility to associate metadata to a Session instance
1 parent 9996a31 commit 0c7af11

File tree

13 files changed

+350
-68
lines changed

13 files changed

+350
-68
lines changed

doc/source/changes/version_0_29.rst.inc

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ New features
7575
False
7676

7777
* allowed arrays to have metadata (e.g. title, description, authors, ...).
78-
Metadata can be accessed using the syntax ``array.meta.name``.
79-
See bellow for use cases:
78+
Array metadata can be accessed using the syntax ``array.meta.name``.
79+
See below for use cases:
8080

8181
>>> # add metadata to/from an array
8282
>>> # for Python <= 3.5
@@ -93,8 +93,8 @@ New features
9393

9494
Warnings:
9595

96-
- Currently, only the HDF (.h5) file format supports saving and loading metadata.
97-
- Metadata are not kept when actions or methods are applied on a array
96+
- Currently, only the HDF (.h5) file format supports saving and loading array metadata.
97+
- Metadata is not kept when actions or methods are applied on an array
9898
except for operations modifying the object in-place, such as `pop[age < 10] = 0`,
9999
and when the method `copy()` is called. Do not add metadata to an array if you know
100100
you will apply actions or methods on it before dumping it.
@@ -127,6 +127,32 @@ New features
127127
3.141592653589793
128128

129129

130+
* allowed sessions to have metadata.
131+
Like for arrays, session metadata can be accessed using the syntax ``session.meta.name``.
132+
See below for use cases:
133+
134+
>>> # add metadata to a session at creation
135+
>>> # Python <= 3.5
136+
>>> s = Session([('arr1', ndtest(2)), ('arr2', ndtest(3)], meta=[('title', 'my title'), ('author', 'John Smith')])
137+
>>> # Python 3.6+
138+
>>> s = Session(arr1=ndtest(2), arr2=ndtest(3), meta=Metadata(title='my title', author='John Smith'))
139+
>>> # show/access metadata
140+
>>> s.meta
141+
title: my title
142+
author: John Smith
143+
144+
Warnings:
145+
146+
- Contrary to array metadata, saving and loading session metadata is supported for
147+
all current session file formats: Excel, CSV and HDF (.h5)
148+
- Metadata is not kept when actions or methods are applied on a session
149+
except for operations modifying a specific array, such as: `s['arr1'] = 0`.
150+
Do not add metadata to a session if you know you will apply actions or methods
151+
on it before dumping it.
152+
153+
Closes :issue:`640`.
154+
155+
130156
.. _misc:
131157

132158
Miscellaneous improvements

larray/core/array.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ class LArray(ABCLArray):
687687
688688
Warnings
689689
--------
690-
Metadata are not kept when actions or methods are applied on a array
690+
Metadata is not kept when actions or methods are applied on an array
691691
except for operations modifying the object in-place, such as: `pop[age < 10] = 0`.
692692
Do not add metadata to an array if you know you will apply actions or methods
693693
on it before dumping it.
@@ -8097,7 +8097,7 @@ def eye(rows, columns=None, k=0, title=None, dtype=None, meta=None):
80978097
# ('FR', 'M'): 2, ('FR', 'F'): 3,
80988098
# ('DE', 'M'): 4, ('DE', 'F'): 5})
80998099

8100-
# TODO: add metadata to returned Session once Session will handle metadata
8100+
81018101
def stack(elements=None, axis=None, title=None, meta=None, **kwargs):
81028102
"""
81038103
Combines several arrays or sessions along an axis.
@@ -8285,7 +8285,7 @@ def stack(elements=None, axis=None, title=None, meta=None, **kwargs):
82858285
except Exception:
82868286
stacked = nan
82878287
res.append((name, stacked))
8288-
return Session(res)
8288+
return Session(res, meta=meta)
82898289
else:
82908290
# XXX : use concat?
82918291
result_axes = AxisCollection.union(*[get_axes(v) for v in values])

larray/core/metadata.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from __future__ import absolute_import, division, print_function
33

44
from collections import OrderedDict
5-
from larray.util.misc import PY2
5+
from larray.util.misc import PY2, basestring
66

77

88
__all__ = ['Metadata']
@@ -31,6 +31,13 @@ def __delattr__(self, key):
3131
od = object.__getattribute__(self, '__odict')
3232
del od[key]
3333

34+
def __reduce__(self):
35+
'Return state information for pickling'
36+
od = object.__getattribute__(self, '__odict')
37+
res = list(od.__reduce__())
38+
res[0] = self.__class__
39+
return tuple(res)
40+
3441
def __dir__(self):
3542
od = object.__getattribute__(self, '__odict')
3643
return list(set(dir(self.__class__)) | set(self.__dict__.keys()) | set(od.keys()))
@@ -56,9 +63,6 @@ def method(self, *args, **kwargs):
5663
__iter__ = method_factory('iter')
5764
__len__ = method_factory('len')
5865

59-
__reduce__ = method_factory('reduce')
60-
__reduce_ex__ = method_factory('reduce_ex')
61-
6266
__reversed__ = method_factory('reversed')
6367

6468
__sizeof__ = method_factory('sizeof')
@@ -143,6 +147,29 @@ class Metadata(AttributeDict):
143147
>>> del arr.meta.creation_date
144148
"""
145149

150+
# TODO: use LArray.from_dict once ready (issue 581)
151+
def __larray__(self):
152+
from larray.core.array import LArray
153+
from larray.core.axis import Axis
154+
return LArray(list(self.values()), Axis(self.keys(), name='metadata'))
155+
156+
@classmethod
157+
def from_array(cls, array):
158+
from larray.core.array import aslarray
159+
array = aslarray(array)
160+
if array.ndim != 1:
161+
raise ValueError("Expected LArray object of dimension 1. Got array of dimension {}".format(array.ndim))
162+
163+
from pandas import to_numeric, to_datetime
164+
165+
def _convert_value(value):
166+
value = to_numeric([value], errors='ignore')[0]
167+
if isinstance(value, basestring):
168+
value = to_datetime(value, errors='ignore', infer_datetime_format=True)
169+
return value
170+
171+
return Metadata([(key, _convert_value(value)) for key, value in zip(array.axes.labels[0], array.data)])
172+
146173
# ---------- IO methods ----------
147174
def to_hdf(self, hdfstore, key):
148175
if len(self):

0 commit comments

Comments
 (0)