12
12
from .variable import as_variable , Variable , Coordinate , broadcast_variables
13
13
14
14
15
- def _get_all_indexes (objects ):
15
+ def _get_joiner (join ):
16
+ if join == 'outer' :
17
+ return functools .partial (functools .reduce , operator .or_ )
18
+ elif join == 'inner' :
19
+ return functools .partial (functools .reduce , operator .and_ )
20
+ elif join == 'left' :
21
+ return operator .itemgetter (0 )
22
+ elif join == 'right' :
23
+ return operator .itemgetter (- 1 )
24
+ else :
25
+ raise ValueError ('invalid value for join: %s' % join )
26
+
27
+
28
+ def _get_all_indexes (objects , exclude = set ()):
16
29
all_indexes = defaultdict (list )
17
30
for obj in objects :
18
31
for k , v in iteritems (obj .indexes ):
19
- all_indexes [k ].append (v )
32
+ if k not in exclude :
33
+ all_indexes [k ].append (v )
20
34
return all_indexes
21
35
22
36
37
+ def _join_indexes (join , objects , exclude = set ()):
38
+ joiner = _get_joiner (join )
39
+ indexes = _get_all_indexes (objects , exclude = exclude )
40
+ # exclude dimensions with all equal indices (the usual case) to avoid
41
+ # unnecessary reindexing work.
42
+ # TODO: don't bother to check equals for left or right joins
43
+ joined_indexes = dict ((k , joiner (v )) for k , v in iteritems (indexes )
44
+ if any (not v [0 ].equals (idx ) for idx in v [1 :]))
45
+ return joined_indexes
46
+
47
+
23
48
def align (* objects , ** kwargs ):
24
49
"""align(*objects, join='inner', copy=True)
25
50
26
51
Given any number of Dataset and/or DataArray objects, returns new
27
52
objects with aligned indexes.
28
53
29
54
Array from the aligned objects are suitable as input to mathematical
30
- operators, because along each dimension they are indexed by the same
31
- indexes.
55
+ operators, because along each dimension they have the same indexes.
32
56
33
57
Missing values (if ``join != 'inner'``) are filled with NaN.
34
58
@@ -39,13 +63,13 @@ def align(*objects, **kwargs):
39
63
join : {'outer', 'inner', 'left', 'right'}, optional
40
64
Method for joining the indexes of the passed objects along each
41
65
dimension:
42
- - 'outer': use the union of object indexes
43
- - 'inner': use the intersection of object indexes
44
- - 'left': use indexes from the first object with each dimension
45
- - 'right': use indexes from the last object with each dimension
66
+ - 'outer': use the union of object indexes
67
+ - 'inner': use the intersection of object indexes
68
+ - 'left': use indexes from the first object with each dimension
69
+ - 'right': use indexes from the last object with each dimension
46
70
copy : bool, optional
47
- If `copy=True`, the returned objects contain all new variables. If
48
- `copy=False` and no reindexing is required then the aligned objects
71
+ If `` copy=True` `, the returned objects contain all new variables. If
72
+ `` copy=False` ` and no reindexing is required then the aligned objects
49
73
will include original variables.
50
74
51
75
Returns
@@ -55,23 +79,27 @@ def align(*objects, **kwargs):
55
79
"""
56
80
join = kwargs .pop ('join' , 'inner' )
57
81
copy = kwargs .pop ('copy' , True )
82
+ if kwargs :
83
+ raise TypeError ('align() got unexpected keyword arguments: %s'
84
+ % list (kwargs ))
58
85
59
- if join == 'outer' :
60
- join_indices = functools .partial (functools .reduce , operator .or_ )
61
- elif join == 'inner' :
62
- join_indices = functools .partial (functools .reduce , operator .and_ )
63
- elif join == 'left' :
64
- join_indices = operator .itemgetter (0 )
65
- elif join == 'right' :
66
- join_indices = operator .itemgetter (- 1 )
86
+ joined_indexes = _join_indexes (join , objects )
87
+ return tuple (obj .reindex (copy = copy , ** joined_indexes ) for obj in objects )
67
88
68
- all_indexes = _get_all_indexes (objects )
69
89
70
- # Exclude dimensions with all equal indices to avoid unnecessary reindexing
71
- # work.
72
- joined_indexes = dict ((k , join_indices (v )) for k , v in iteritems (all_indexes )
73
- if any (not v [0 ].equals (idx ) for idx in v [1 :]))
90
+ def partial_align (* objects , ** kwargs ):
91
+ """partial_align(*objects, join='inner', copy=True, exclude=set()
92
+
93
+ Like align, but don't align along dimensions in exclude. Not public API.
94
+ """
95
+ join = kwargs .pop ('join' , 'inner' )
96
+ copy = kwargs .pop ('copy' , True )
97
+ exclude = kwargs .pop ('exclude' , set ())
98
+ if kwargs :
99
+ raise TypeError ('align() got unexpected keyword arguments: %s'
100
+ % list (kwargs ))
74
101
102
+ joined_indexes = _join_indexes (join , objects , exclude = exclude )
75
103
return tuple (obj .reindex (copy = copy , ** joined_indexes ) for obj in objects )
76
104
77
105
0 commit comments