apmtools 0.2.6__tar.gz → 0.2.8__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.
- {apmtools-0.2.6 → apmtools-0.2.8}/PKG-INFO +1 -1
- {apmtools-0.2.6 → apmtools-0.2.8}/pyproject.toml +1 -1
- {apmtools-0.2.6 → apmtools-0.2.8}/src/apmtools/classes.py +44 -47
- {apmtools-0.2.6 → apmtools-0.2.8}/src/apmtools/shiny/summary.py +37 -6
- {apmtools-0.2.6 → apmtools-0.2.8}/.gitignore +0 -0
- {apmtools-0.2.6 → apmtools-0.2.8}/LICENSE +0 -0
- {apmtools-0.2.6 → apmtools-0.2.8}/README.md +0 -0
- {apmtools-0.2.6 → apmtools-0.2.8}/src/apmtools/__init__.py +0 -0
- {apmtools-0.2.6 → apmtools-0.2.8}/src/apmtools/data_processing.py +0 -0
- {apmtools-0.2.6 → apmtools-0.2.8}/src/apmtools/functions.py +0 -0
- {apmtools-0.2.6 → apmtools-0.2.8}/src/apmtools/legacy.py +0 -0
- {apmtools-0.2.6 → apmtools-0.2.8}/src/apmtools/shiny/__init__.py +0 -0
- {apmtools-0.2.6 → apmtools-0.2.8}/src/apmtools/units.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: apmtools
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.008
|
|
4
4
|
Summary: A collection of tools for processing air pollution monitoring data
|
|
5
5
|
Project-URL: Homepage, https://github.com/federlorenz/apmtools
|
|
6
6
|
Author-email: Federico Lorenzetti <lorenzetti.federico@gmail.com>
|
|
@@ -884,60 +884,57 @@ class Summary(pd.DataFrame):
|
|
|
884
884
|
return self
|
|
885
885
|
|
|
886
886
|
def subset(self, filter_dict={}, filter_style='all'):
|
|
887
|
+
"""Return rows matching values specified in ``filter_dict``.
|
|
888
|
+
|
|
889
|
+
Parameters
|
|
890
|
+
----------
|
|
891
|
+
filter_dict : dict
|
|
892
|
+
Mapping of column names to iterables of accepted values.
|
|
893
|
+
filter_style : {'all', 'any', 'negative all', 'negative any'}
|
|
894
|
+
``all`` keeps rows matching every supplied condition; ``any`` keeps
|
|
895
|
+
rows matching at least one condition. ``negative all`` keeps rows
|
|
896
|
+
that match none of the supplied conditions, and ``negative any``
|
|
897
|
+
keeps rows that do not match any individual condition.
|
|
898
|
+
|
|
899
|
+
Notes
|
|
900
|
+
-----
|
|
901
|
+
Filtering is performed positionally rather than assuming that the
|
|
902
|
+
DataFrame index is ``0..n-1``. This is important because ``Summary``
|
|
903
|
+
objects commonly acquire non-contiguous indices after previous
|
|
904
|
+
filtering operations.
|
|
887
905
|
"""
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
attrib is an attribute of the elements of dictionary, and attrib_value is a list
|
|
891
|
-
of the values of such attrib that the elements of returned dictionary can have
|
|
892
|
-
specify filter_style='all' if all conditions should be met to be included in the return dictionary, specify filter_style='any' for including when any condition is met. Default is 'all'.
|
|
893
|
-
"""
|
|
894
|
-
if type(filter_dict) != type(dict()):
|
|
906
|
+
|
|
907
|
+
if not isinstance(filter_dict, dict):
|
|
895
908
|
print("subset function error: type filter_dict should be dict")
|
|
896
909
|
return
|
|
910
|
+
|
|
897
911
|
return_dict = copy.deepcopy(self)
|
|
898
912
|
a = {}
|
|
899
913
|
|
|
900
|
-
if filter_style
|
|
901
|
-
|
|
902
|
-
for i, j in filter_dict.items():
|
|
903
|
-
if (i in return_dict.columns):
|
|
904
|
-
for z in range(len(return_dict)):
|
|
905
|
-
if return_dict.loc[z, i] in j:
|
|
906
|
-
filtering_list[z] = True
|
|
907
|
-
else:
|
|
908
|
-
filtering_list[z] = False
|
|
909
|
-
return_dict = return_dict.loc[filtering_list]
|
|
914
|
+
if filter_style not in {'all', 'any', 'negative all', 'negative any'}:
|
|
915
|
+
return return_dict
|
|
910
916
|
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
filtering_list = [True]*(len(return_dict))
|
|
933
|
-
for i, j in filter_dict.items():
|
|
934
|
-
if (i in return_dict.columns):
|
|
935
|
-
for z in range(len(return_dict)):
|
|
936
|
-
if return_dict.loc[z, i] in j:
|
|
937
|
-
filtering_list[z] = False
|
|
938
|
-
return_dict = return_dict.loc[filtering_list]
|
|
939
|
-
|
|
940
|
-
return return_dict
|
|
917
|
+
# Only conditions referring to existing columns can be evaluated.
|
|
918
|
+
conditions = []
|
|
919
|
+
for column, values in filter_dict.items():
|
|
920
|
+
if column in return_dict.columns:
|
|
921
|
+
conditions.append(return_dict[column].isin(values).to_numpy())
|
|
922
|
+
|
|
923
|
+
if not conditions:
|
|
924
|
+
return return_dict
|
|
925
|
+
|
|
926
|
+
conditions = pd.DataFrame(conditions, dtype=bool)
|
|
927
|
+
|
|
928
|
+
if filter_style == 'all':
|
|
929
|
+
mask = conditions.all(axis=0).to_numpy()
|
|
930
|
+
elif filter_style == 'any':
|
|
931
|
+
mask = conditions.any(axis=0).to_numpy()
|
|
932
|
+
elif filter_style == 'negative all':
|
|
933
|
+
mask = (~conditions).all(axis=0).to_numpy()
|
|
934
|
+
else: # negative any
|
|
935
|
+
mask = (~conditions).any(axis=0).to_numpy()
|
|
936
|
+
|
|
937
|
+
return return_dict.loc[mask]
|
|
941
938
|
|
|
942
939
|
def show(self, number=0, key=None):
|
|
943
940
|
"""
|
|
@@ -351,12 +351,43 @@ def create_summary_app(
|
|
|
351
351
|
)
|
|
352
352
|
|
|
353
353
|
if selected_plot == "histogram":
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
354
|
+
if group_columns:
|
|
355
|
+
# With grouping, overlay one histogram per group on the
|
|
356
|
+
# same axes. ``group`` is the color dimension rather
|
|
357
|
+
# than the selected variable, so each group gets its own
|
|
358
|
+
# histogram. Transparency makes overlapping groups
|
|
359
|
+
# directly comparable.
|
|
360
|
+
group_column = "__plot_group"
|
|
361
|
+
long_df = plot_df[[group_column, *y_columns]].melt(
|
|
362
|
+
id_vars=[group_column],
|
|
363
|
+
var_name="variable",
|
|
364
|
+
value_name="value",
|
|
365
|
+
)
|
|
366
|
+
fig = px.histogram(
|
|
367
|
+
long_df,
|
|
368
|
+
x="value",
|
|
369
|
+
color=group_column,
|
|
370
|
+
nbins=int(input.bins()),
|
|
371
|
+
barmode="overlay",
|
|
372
|
+
opacity=0.45,
|
|
373
|
+
facet_row=("variable" if len(y_columns) > 1 else None),
|
|
374
|
+
)
|
|
375
|
+
# Keep the groups as the legend entries rather than the
|
|
376
|
+
# selected Y variables.
|
|
377
|
+
fig.update_traces(marker_line_width=0)
|
|
378
|
+
else:
|
|
379
|
+
long_df = plot_df[y_columns].melt(
|
|
380
|
+
var_name="variable", value_name="value"
|
|
381
|
+
)
|
|
382
|
+
fig = px.histogram(
|
|
383
|
+
long_df,
|
|
384
|
+
x="value",
|
|
385
|
+
color="variable",
|
|
386
|
+
nbins=int(input.bins()),
|
|
387
|
+
barmode="overlay" if len(
|
|
388
|
+
y_columns) > 1 else "relative",
|
|
389
|
+
opacity=0.65 if len(y_columns) > 1 else 1.0,
|
|
390
|
+
)
|
|
360
391
|
elif selected_plot == "box":
|
|
361
392
|
if not group_columns:
|
|
362
393
|
long_df = plot_df[y_columns].melt(
|
|
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
|