flatbread 0.1.3__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flatbread-0.1.3 → flatbread-0.1.4}/PKG-INFO +1 -1
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/accessors/dataframe.py +4 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/accessors/series.py +4 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/agg/aggregation.py +18 -1
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/agg/totals.py +6 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/chaining.py +24 -4
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/config/config.defaults.json +1 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/pyproject.toml +1 -1
- {flatbread-0.1.3 → flatbread-0.1.4}/.gitignore +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/environment.yml +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/__init__.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/accessors/index.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/config.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/percentages.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/render/config.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/render/constants.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/render/display.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/render/tablespec.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/render/template.jinja.html +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/render/template.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/testing/dataframe.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/flatbread/tooling.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/license.md +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/readme.md +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/tests/__init__.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/tests/aggregate/__init__.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/tests/aggregate/test_percentages.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/tests/aggregate/test_totals.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/tests/test_axes.py +0 -0
- {flatbread-0.1.3 → flatbread-0.1.4}/tests/test_levels.py +0 -0
|
@@ -65,6 +65,7 @@ class PitaFrame(PitaDisplayMixin):
|
|
|
65
65
|
axis: int = 0,
|
|
66
66
|
level: int|str|list[int|str] = 0,
|
|
67
67
|
label: str = None,
|
|
68
|
+
include_level_name: bool = False,
|
|
68
69
|
ignore_keys: str|list[str]|None = None,
|
|
69
70
|
_fill: str = '',
|
|
70
71
|
) -> pd.DataFrame:
|
|
@@ -99,6 +100,7 @@ class PitaFrame(PitaDisplayMixin):
|
|
|
99
100
|
axis = axis,
|
|
100
101
|
level = level,
|
|
101
102
|
label = label,
|
|
103
|
+
include_level_name = include_level_name,
|
|
102
104
|
ignore_keys = ignore_keys,
|
|
103
105
|
_fill = _fill,
|
|
104
106
|
)
|
|
@@ -252,6 +254,7 @@ class PitaFrame(PitaDisplayMixin):
|
|
|
252
254
|
axis: int = 2,
|
|
253
255
|
level: int|str|list[int|str] = 0,
|
|
254
256
|
label: str|None = None,
|
|
257
|
+
include_level_name: bool = False,
|
|
255
258
|
ignore_keys: str|list[str]|None = None,
|
|
256
259
|
_fill: str = '',
|
|
257
260
|
) -> pd.DataFrame:
|
|
@@ -279,6 +282,7 @@ class PitaFrame(PitaDisplayMixin):
|
|
|
279
282
|
axis = axis,
|
|
280
283
|
level = level,
|
|
281
284
|
label = label,
|
|
285
|
+
include_level_name = include_level_name,
|
|
282
286
|
ignore_keys = ignore_keys,
|
|
283
287
|
_fill = _fill,
|
|
284
288
|
)
|
|
@@ -60,6 +60,7 @@ class PitaSeries(PitaDisplayMixin):
|
|
|
60
60
|
aggfunc: str|Callable,
|
|
61
61
|
level: int|str|list[int|str] = 0,
|
|
62
62
|
label: str = None,
|
|
63
|
+
include_level_name: bool = False,
|
|
63
64
|
ignore_keys: str|list[str]|None = None,
|
|
64
65
|
_fill: str = '',
|
|
65
66
|
) -> pd.Series:
|
|
@@ -91,6 +92,7 @@ class PitaSeries(PitaDisplayMixin):
|
|
|
91
92
|
aggfunc,
|
|
92
93
|
level = level,
|
|
93
94
|
label = label,
|
|
95
|
+
include_level_name = include_level_name,
|
|
94
96
|
ignore_keys = ignore_keys,
|
|
95
97
|
_fill = _fill,
|
|
96
98
|
)
|
|
@@ -256,6 +258,7 @@ class PitaSeries(PitaDisplayMixin):
|
|
|
256
258
|
self,
|
|
257
259
|
level: int|str|list[int|str] = 0,
|
|
258
260
|
label: str|None = None,
|
|
261
|
+
include_level_name: bool = False,
|
|
259
262
|
ignore_keys: str|list[str]|None = None,
|
|
260
263
|
_fill: str = '',
|
|
261
264
|
) -> pd.Series:
|
|
@@ -280,6 +283,7 @@ class PitaSeries(PitaDisplayMixin):
|
|
|
280
283
|
self._obj,
|
|
281
284
|
level = level,
|
|
282
285
|
label = label,
|
|
286
|
+
include_level_name = include_level_name,
|
|
283
287
|
ignore_keys = ignore_keys,
|
|
284
288
|
_fill = _fill,
|
|
285
289
|
)
|
|
@@ -109,6 +109,7 @@ def add_subagg(
|
|
|
109
109
|
*args,
|
|
110
110
|
level: int|str|list[int|str] = 0,
|
|
111
111
|
label: str|None = None,
|
|
112
|
+
include_level_name: bool = False,
|
|
112
113
|
ignore_keys: str|list[str]|None = None,
|
|
113
114
|
**kwargs,
|
|
114
115
|
):
|
|
@@ -123,6 +124,7 @@ def _(
|
|
|
123
124
|
*args,
|
|
124
125
|
level: int|str|list[int|str] = 0,
|
|
125
126
|
label: str|None = None,
|
|
127
|
+
include_level_name: bool = False,
|
|
126
128
|
ignore_keys: str|list[str]|None = None,
|
|
127
129
|
_fill = '',
|
|
128
130
|
**kwargs,
|
|
@@ -134,6 +136,7 @@ def _(
|
|
|
134
136
|
*args,
|
|
135
137
|
level = level,
|
|
136
138
|
label = label,
|
|
139
|
+
include_level_name = include_level_name,
|
|
137
140
|
ignore_keys = ignore_keys,
|
|
138
141
|
_fill = _fill,
|
|
139
142
|
**kwargs,
|
|
@@ -150,6 +153,7 @@ def _(
|
|
|
150
153
|
axis: int = 0,
|
|
151
154
|
level: int|str|list[int|str] = 0,
|
|
152
155
|
label: str|None = None,
|
|
156
|
+
include_level_name: bool = False,
|
|
153
157
|
ignore_keys: str|list[str]|None = None,
|
|
154
158
|
_fill = '',
|
|
155
159
|
**kwargs,
|
|
@@ -161,6 +165,7 @@ def _(
|
|
|
161
165
|
*args,
|
|
162
166
|
level = level,
|
|
163
167
|
label = label,
|
|
168
|
+
include_level_name = include_level_name,
|
|
164
169
|
ignore_keys = ignore_keys,
|
|
165
170
|
_fill = _fill,
|
|
166
171
|
**kwargs,
|
|
@@ -176,6 +181,7 @@ def _subagg_implementation(
|
|
|
176
181
|
*args,
|
|
177
182
|
level: int|str|list[int|str] = 0,
|
|
178
183
|
label: str|None = None,
|
|
184
|
+
include_level_name: bool = False,
|
|
179
185
|
ignore_keys: str|list[str]|None = None,
|
|
180
186
|
_fill = '',
|
|
181
187
|
**kwargs,
|
|
@@ -196,8 +202,19 @@ def _subagg_implementation(
|
|
|
196
202
|
for levels, group in groups:
|
|
197
203
|
# create key
|
|
198
204
|
levels = (levels,) if pd.api.types.is_scalar(levels) else levels
|
|
205
|
+
|
|
206
|
+
# format label with level name if requested
|
|
207
|
+
current_label = label
|
|
208
|
+
if include_level_name:
|
|
209
|
+
# get level name
|
|
210
|
+
if isinstance(level, (int, str)):
|
|
211
|
+
level_name = names[level] if isinstance(level, int) else level
|
|
212
|
+
current_label = f"{label} {level_name}"
|
|
213
|
+
elif isinstance(levels[-1], str):
|
|
214
|
+
current_label = f"{label} {levels[-1]}"
|
|
215
|
+
|
|
199
216
|
padding = [_fill] * (len(names) - len(levels) - 1)
|
|
200
|
-
key = list(levels) + [
|
|
217
|
+
key = list(levels) + [current_label] + padding
|
|
201
218
|
|
|
202
219
|
# ignore totals and subtotal rows when aggregating
|
|
203
220
|
rows = chaining.get_data_mask(group.index, ignore_keys)
|
|
@@ -95,6 +95,7 @@ def add_subtotals(
|
|
|
95
95
|
def _(
|
|
96
96
|
data: pd.Series,
|
|
97
97
|
level: int|str|list[int|str] = 0,
|
|
98
|
+
include_level_name: bool = False,
|
|
98
99
|
label: str = 'Subtotals',
|
|
99
100
|
ignore_keys: str|list[str]|None = 'Totals',
|
|
100
101
|
_fill: str|None = '',
|
|
@@ -104,6 +105,7 @@ def _(
|
|
|
104
105
|
'sum',
|
|
105
106
|
level = level,
|
|
106
107
|
label = label,
|
|
108
|
+
include_level_name = include_level_name,
|
|
107
109
|
ignore_keys = ignore_keys,
|
|
108
110
|
_fill = _fill,
|
|
109
111
|
)
|
|
@@ -118,6 +120,7 @@ def _(
|
|
|
118
120
|
axis: int = 0,
|
|
119
121
|
level: int|str|list[int|str] = 0,
|
|
120
122
|
label: str = 'Subtotals',
|
|
123
|
+
include_level_name: bool = False,
|
|
121
124
|
ignore_keys: str|list[str]|None = 'Totals',
|
|
122
125
|
_fill: str = '',
|
|
123
126
|
) -> pd.DataFrame:
|
|
@@ -128,6 +131,7 @@ def _(
|
|
|
128
131
|
axis = axis,
|
|
129
132
|
level = level,
|
|
130
133
|
label = label,
|
|
134
|
+
include_level_name = include_level_name,
|
|
131
135
|
ignore_keys = ignore_keys,
|
|
132
136
|
_fill = _fill,
|
|
133
137
|
)
|
|
@@ -139,6 +143,7 @@ def _(
|
|
|
139
143
|
axis = 0,
|
|
140
144
|
level = level,
|
|
141
145
|
label = label,
|
|
146
|
+
include_level_name = include_level_name,
|
|
142
147
|
ignore_keys = ignore_keys,
|
|
143
148
|
_fill = _fill,
|
|
144
149
|
)
|
|
@@ -147,6 +152,7 @@ def _(
|
|
|
147
152
|
axis = 1,
|
|
148
153
|
level = level,
|
|
149
154
|
label = label,
|
|
155
|
+
include_level_name = include_level_name,
|
|
150
156
|
ignore_keys = ignore_keys,
|
|
151
157
|
_fill = _fill,
|
|
152
158
|
)
|
|
@@ -13,18 +13,38 @@ def get_data_mask(index, ignore_keys):
|
|
|
13
13
|
index (pd.Index):
|
|
14
14
|
The index used for determining if a row/column contains data or not.
|
|
15
15
|
ignore_keys (list[str]):
|
|
16
|
-
List of index keys indicating that a row/column is *not* a data column. If the index is a MultiIndex then a row/column will be ignored if the key is in the keys of the index, else a row/column will be ignored if it is equal to the key in the index.
|
|
16
|
+
List of index keys indicating that a row/column is *not* a data column. If the index is a MultiIndex then a row/column will be ignored if the key is in the keys of the index, else a row/column will be ignored if it is equal to or a prefix of the key in the index.
|
|
17
17
|
|
|
18
18
|
Returns
|
|
19
19
|
-------
|
|
20
20
|
pd.Index:
|
|
21
21
|
Boolean index indicating which rows/columns refer to data.
|
|
22
22
|
"""
|
|
23
|
+
if ignore_keys is None:
|
|
24
|
+
return pd.Series(True, index=index)
|
|
25
|
+
|
|
26
|
+
# Convert single string to list
|
|
27
|
+
if isinstance(ignore_keys, str):
|
|
28
|
+
ignore_keys = [ignore_keys]
|
|
29
|
+
|
|
30
|
+
def should_keep(value):
|
|
31
|
+
# direct match
|
|
32
|
+
if value in ignore_keys:
|
|
33
|
+
return False
|
|
34
|
+
|
|
35
|
+
# check for prefix
|
|
36
|
+
if isinstance(value, str):
|
|
37
|
+
for key in ignore_keys:
|
|
38
|
+
if isinstance(key, str) and value.startswith(key):
|
|
39
|
+
return False
|
|
40
|
+
return True
|
|
41
|
+
|
|
23
42
|
if isinstance(index, pd.MultiIndex):
|
|
24
|
-
|
|
43
|
+
result = [all(should_keep(el) for el in idx) for idx in index]
|
|
25
44
|
else:
|
|
26
|
-
|
|
27
|
-
|
|
45
|
+
result = [should_keep(idx) for idx in index]
|
|
46
|
+
|
|
47
|
+
return pd.Series(result, index=index)
|
|
28
48
|
|
|
29
49
|
|
|
30
50
|
def persist_ignored(component: str, label: str) -> Callable:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|