numdaplot 0.1.0__py3-none-any.whl
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.
- numdaplot/__init__.py +506 -0
- numdaplot/arrays/__init__.py +5 -0
- numdaplot/arrays/array.py +92 -0
- numdaplot/arrays/array_arithmetic.py +404 -0
- numdaplot/arrays/array_calculation.py +143 -0
- numdaplot/arrays/array_conversion.py +150 -0
- numdaplot/arrays/array_creation.py +371 -0
- numdaplot/arrays/array_data.py +281 -0
- numdaplot/arrays/array_layout.py +179 -0
- numdaplot/arrays/array_logic.py +227 -0
- numdaplot/arrays/array_reflected_arithmetic.py +334 -0
- numdaplot/arrays/array_refusals.py +339 -0
- numdaplot/arrays/array_selection.py +195 -0
- numdaplot/arrays/array_sorting.py +59 -0
- numdaplot/arrays/axis_number.py +58 -0
- numdaplot/arrays/calculation/__init__.py +5 -0
- numdaplot/arrays/calculation/counting_statistics.py +325 -0
- numdaplot/arrays/calculation/location_statistics.py +268 -0
- numdaplot/arrays/calculation/math_function_values.py +183 -0
- numdaplot/arrays/calculation/statistic_values.py +209 -0
- numdaplot/arrays/calculation/time_function_values.py +419 -0
- numdaplot/arrays/conversion/__init__.py +5 -0
- numdaplot/arrays/conversion/array_text.py +62 -0
- numdaplot/arrays/conversion/equality_check.py +72 -0
- numdaplot/arrays/conversion/python_values.py +70 -0
- numdaplot/arrays/conversion/time_text.py +290 -0
- numdaplot/arrays/creation/__init__.py +5 -0
- numdaplot/arrays/creation/date_parts.py +89 -0
- numdaplot/arrays/creation/date_parts_values.py +437 -0
- numdaplot/arrays/creation/distribution.py +54 -0
- numdaplot/arrays/creation/filled_values.py +58 -0
- numdaplot/arrays/creation/list_conversion.py +311 -0
- numdaplot/arrays/creation/list_shape.py +97 -0
- numdaplot/arrays/creation/normal.py +65 -0
- numdaplot/arrays/creation/numpy_conversion.py +149 -0
- numdaplot/arrays/creation/random_integers.py +104 -0
- numdaplot/arrays/creation/random_values.py +97 -0
- numdaplot/arrays/creation/range_values.py +73 -0
- numdaplot/arrays/creation/spacing.py +84 -0
- numdaplot/arrays/creation/spacing_values.py +63 -0
- numdaplot/arrays/creation/uniform.py +63 -0
- numdaplot/arrays/equality.py +68 -0
- numdaplot/arrays/layout/__init__.py +5 -0
- numdaplot/arrays/layout/sorting_values.py +113 -0
- numdaplot/arrays/layout/unique_values.py +49 -0
- numdaplot/arrays/mapping/__init__.py +5 -0
- numdaplot/arrays/mapping/mapped_values.py +286 -0
- numdaplot/arrays/mapping/unmatched.py +50 -0
- numdaplot/arrays/mapping/value_change.py +55 -0
- numdaplot/arrays/mapping/value_mapping.py +161 -0
- numdaplot/arrays/math_functions/__init__.py +5 -0
- numdaplot/arrays/math_functions/absolute.py +27 -0
- numdaplot/arrays/math_functions/cosine.py +28 -0
- numdaplot/arrays/math_functions/exponential.py +27 -0
- numdaplot/arrays/math_functions/logarithm.py +72 -0
- numdaplot/arrays/math_functions/math_function.py +58 -0
- numdaplot/arrays/math_functions/round.py +58 -0
- numdaplot/arrays/math_functions/sine.py +28 -0
- numdaplot/arrays/math_functions/square_root.py +27 -0
- numdaplot/arrays/operations/__init__.py +5 -0
- numdaplot/arrays/operations/boolean_operands.py +48 -0
- numdaplot/arrays/operations/combination.py +157 -0
- numdaplot/arrays/operations/float_errors.py +170 -0
- numdaplot/arrays/operations/integer_bounds.py +175 -0
- numdaplot/arrays/operations/integer_rules.py +397 -0
- numdaplot/arrays/operations/operand.py +139 -0
- numdaplot/arrays/operations/time_arithmetic.py +479 -0
- numdaplot/arrays/operations/time_bounds.py +286 -0
- numdaplot/arrays/operations/time_result_bounds.py +397 -0
- numdaplot/arrays/operations/transformation.py +54 -0
- numdaplot/arrays/operations/type_requirements.py +94 -0
- numdaplot/arrays/replacement.py +66 -0
- numdaplot/arrays/selection/__init__.py +5 -0
- numdaplot/arrays/selection/comparison_masks.py +131 -0
- numdaplot/arrays/selection/membership_masks.py +118 -0
- numdaplot/arrays/selection/missing_mask.py +50 -0
- numdaplot/arrays/selection/region_index.py +178 -0
- numdaplot/arrays/selection/replaced_values.py +120 -0
- numdaplot/arrays/selection/rule_mask.py +83 -0
- numdaplot/arrays/selection/time_reference.py +172 -0
- numdaplot/arrays/shape.py +74 -0
- numdaplot/arrays/type_match.py +51 -0
- numdaplot/data_types/__init__.py +5 -0
- numdaplot/data_types/library.py +57 -0
- numdaplot/data_types/numpy_mapping.py +207 -0
- numdaplot/data_types/pandas_mapping.py +114 -0
- numdaplot/data_types/time_of_day.py +292 -0
- numdaplot/data_types/type.py +224 -0
- numdaplot/data_types/value_family.py +149 -0
- numdaplot/data_types/value_type.py +147 -0
- numdaplot/dates/__init__.py +5 -0
- numdaplot/dates/custom_date_format.py +83 -0
- numdaplot/dates/date_format.py +120 -0
- numdaplot/dates/date_part.py +59 -0
- numdaplot/dates/date_part_unit.py +153 -0
- numdaplot/dates/date_period.py +57 -0
- numdaplot/dates/duration_in.py +58 -0
- numdaplot/dates/duration_unit.py +90 -0
- numdaplot/dates/period_unit.py +101 -0
- numdaplot/dates/time_function.py +56 -0
- numdaplot/dates/time_zone.py +68 -0
- numdaplot/dates/time_zone_change.py +71 -0
- numdaplot/dates/time_zone_mode.py +81 -0
- numdaplot/dates/to_duration.py +58 -0
- numdaplot/errors/__init__.py +7 -0
- numdaplot/errors/broadcast_warning.py +36 -0
- numdaplot/errors/calculation_warning.py +35 -0
- numdaplot/errors/cell_out_of_range_error.py +77 -0
- numdaplot/errors/column_not_found_error.py +64 -0
- numdaplot/errors/conflicting_settings_error.py +60 -0
- numdaplot/errors/dimension_error.py +62 -0
- numdaplot/errors/display_warning.py +32 -0
- numdaplot/errors/duplicate_column_error.py +82 -0
- numdaplot/errors/duplicate_label_error.py +55 -0
- numdaplot/errors/duplicate_statistic_error.py +55 -0
- numdaplot/errors/duplicate_value_error.py +54 -0
- numdaplot/errors/empty_array_error.py +55 -0
- numdaplot/errors/empty_list_error.py +52 -0
- numdaplot/errors/empty_region_error.py +34 -0
- numdaplot/errors/empty_text_error.py +34 -0
- numdaplot/errors/empty_total_error.py +62 -0
- numdaplot/errors/empty_values_error.py +34 -0
- numdaplot/errors/file_access_error.py +70 -0
- numdaplot/errors/file_exists_error.py +62 -0
- numdaplot/errors/file_not_found_error.py +56 -0
- numdaplot/errors/incompatible_charts_error.py +80 -0
- numdaplot/errors/incompatible_types_error.py +104 -0
- numdaplot/errors/integer_overflow_error.py +61 -0
- numdaplot/errors/invalid_base_error.py +52 -0
- numdaplot/errors/invalid_bin_width_error.py +66 -0
- numdaplot/errors/invalid_bounds_error.py +58 -0
- numdaplot/errors/invalid_chart_data_error.py +81 -0
- numdaplot/errors/invalid_color_count_error.py +63 -0
- numdaplot/errors/invalid_color_error.py +51 -0
- numdaplot/errors/invalid_column_name_error.py +52 -0
- numdaplot/errors/invalid_conversion_error.py +119 -0
- numdaplot/errors/invalid_count_error.py +61 -0
- numdaplot/errors/invalid_date_format_error.py +51 -0
- numdaplot/errors/invalid_deviation_error.py +52 -0
- numdaplot/errors/invalid_fraction_error.py +51 -0
- numdaplot/errors/invalid_label_count_error.py +61 -0
- numdaplot/errors/invalid_limits_error.py +111 -0
- numdaplot/errors/invalid_opacity_error.py +52 -0
- numdaplot/errors/invalid_point_size_error.py +52 -0
- numdaplot/errors/invalid_position_error.py +106 -0
- numdaplot/errors/invalid_resolution_error.py +51 -0
- numdaplot/errors/invalid_rotation_error.py +53 -0
- numdaplot/errors/invalid_seed_error.py +53 -0
- numdaplot/errors/invalid_separator_error.py +52 -0
- numdaplot/errors/invalid_shape_error.py +52 -0
- numdaplot/errors/invalid_sheet_name_error.py +54 -0
- numdaplot/errors/invalid_size_error.py +58 -0
- numdaplot/errors/invalid_step_error.py +77 -0
- numdaplot/errors/invalid_suffixes_error.py +61 -0
- numdaplot/errors/invalid_time_zone_change_error.py +63 -0
- numdaplot/errors/invalid_type_error.py +79 -0
- numdaplot/errors/irregular_list_error.py +36 -0
- numdaplot/errors/join_relation_error.py +183 -0
- numdaplot/errors/missing_dependency_error.py +58 -0
- numdaplot/errors/missing_type_error.py +36 -0
- numdaplot/errors/missing_value_error.py +62 -0
- numdaplot/errors/not_single_value_error.py +53 -0
- numdaplot/errors/numdaplot_error.py +25 -0
- numdaplot/errors/numdaplot_warning.py +34 -0
- numdaplot/errors/occupied_cell_error.py +63 -0
- numdaplot/errors/out_of_domain_error.py +70 -0
- numdaplot/errors/readability_warning.py +35 -0
- numdaplot/errors/refused_operation_error.py +64 -0
- numdaplot/errors/refused_setting_error.py +60 -0
- numdaplot/errors/rejected_dates.py +60 -0
- numdaplot/errors/repeated_key.py +36 -0
- numdaplot/errors/shape_mismatch_error.py +67 -0
- numdaplot/errors/time_overflow_error.py +131 -0
- numdaplot/errors/time_zone_mismatch_error.py +83 -0
- numdaplot/errors/unknown_time_zone_error.py +51 -0
- numdaplot/errors/unmatched_value_error.py +81 -0
- numdaplot/errors/unsupported_image_format_error.py +56 -0
- numdaplot/errors/unsupported_index_error.py +38 -0
- numdaplot/errors/unsupported_missing_error.py +129 -0
- numdaplot/errors/unsupported_type_error.py +62 -0
- numdaplot/errors/value_conversion_error.py +215 -0
- numdaplot/ordering/__init__.py +5 -0
- numdaplot/ordering/missing_position.py +46 -0
- numdaplot/ordering/order.py +46 -0
- numdaplot/package_version.py +36 -0
- numdaplot/plots/__init__.py +5 -0
- numdaplot/plots/chart_layer.py +47 -0
- numdaplot/plots/charts/__init__.py +5 -0
- numdaplot/plots/charts/bar_chart.py +98 -0
- numdaplot/plots/charts/bar_layout.py +58 -0
- numdaplot/plots/charts/bin_count.py +61 -0
- numdaplot/plots/charts/bin_width.py +78 -0
- numdaplot/plots/charts/box_chart.py +97 -0
- numdaplot/plots/charts/cell_values.py +61 -0
- numdaplot/plots/charts/chart.py +59 -0
- numdaplot/plots/charts/chart_settings.py +105 -0
- numdaplot/plots/charts/color_scale.py +147 -0
- numdaplot/plots/charts/heatmap_chart.py +92 -0
- numdaplot/plots/charts/histogram_chart.py +93 -0
- numdaplot/plots/charts/line_chart.py +100 -0
- numdaplot/plots/charts/line_type.py +75 -0
- numdaplot/plots/charts/marker_shape.py +113 -0
- numdaplot/plots/charts/missing_chart.py +60 -0
- numdaplot/plots/charts/missing_map_chart.py +27 -0
- numdaplot/plots/charts/orientation.py +58 -0
- numdaplot/plots/charts/outliers.py +49 -0
- numdaplot/plots/charts/percentages.py +55 -0
- numdaplot/plots/charts/pie_chart.py +87 -0
- numdaplot/plots/charts/scatter_chart.py +159 -0
- numdaplot/plots/charts/value_axis.py +66 -0
- numdaplot/plots/data/__init__.py +5 -0
- numdaplot/plots/data/array_values.py +128 -0
- numdaplot/plots/data/chart_data.py +143 -0
- numdaplot/plots/data/chart_values.py +109 -0
- numdaplot/plots/data/column_reading.py +468 -0
- numdaplot/plots/data/heatmap_values.py +63 -0
- numdaplot/plots/data/missing_cells.py +165 -0
- numdaplot/plots/data/pie_values.py +215 -0
- numdaplot/plots/data/point_values.py +249 -0
- numdaplot/plots/data/position_kind.py +83 -0
- numdaplot/plots/data/renamed_layers.py +340 -0
- numdaplot/plots/data/sample_values.py +160 -0
- numdaplot/plots/data/shown_columns.py +248 -0
- numdaplot/plots/data/table_values.py +256 -0
- numdaplot/plots/data/unique_labels.py +45 -0
- numdaplot/plots/drawing/__init__.py +5 -0
- numdaplot/plots/drawing/bar_drawing.py +316 -0
- numdaplot/plots/drawing/box_drawing.py +344 -0
- numdaplot/plots/drawing/cell_merging.py +237 -0
- numdaplot/plots/drawing/chart_texts.py +124 -0
- numdaplot/plots/drawing/color_bar.py +57 -0
- numdaplot/plots/drawing/color_scale_values.py +120 -0
- numdaplot/plots/drawing/default_labels.py +41 -0
- numdaplot/plots/drawing/drawn_chart.py +50 -0
- numdaplot/plots/drawing/grid_axes.py +75 -0
- numdaplot/plots/drawing/heatmap_drawing.py +313 -0
- numdaplot/plots/drawing/histogram_drawing.py +350 -0
- numdaplot/plots/drawing/label_room.py +344 -0
- numdaplot/plots/drawing/label_thinning.py +216 -0
- numdaplot/plots/drawing/layer_alignment.py +319 -0
- numdaplot/plots/drawing/layer_colors.py +123 -0
- numdaplot/plots/drawing/line_drawing.py +85 -0
- numdaplot/plots/drawing/marker_codes.py +20 -0
- numdaplot/plots/drawing/missing_drawing.py +360 -0
- numdaplot/plots/drawing/moment_period_formatter.py +253 -0
- numdaplot/plots/drawing/pie_drawing.py +185 -0
- numdaplot/plots/drawing/plot_axes.py +38 -0
- numdaplot/plots/drawing/plot_drawing.py +288 -0
- numdaplot/plots/drawing/plot_theme.py +45 -0
- numdaplot/plots/drawing/position_axis.py +278 -0
- numdaplot/plots/drawing/scatter_drawing.py +364 -0
- numdaplot/plots/drawing/series_colors.py +177 -0
- numdaplot/plots/drawing/size_inches.py +45 -0
- numdaplot/plots/drawing/style_drawing.py +410 -0
- numdaplot/plots/drawing/text_contrast.py +44 -0
- numdaplot/plots/drawing/tick_rotation.py +354 -0
- numdaplot/plots/drawing/time_axis.py +212 -0
- numdaplot/plots/drawing/whole_numbers.py +72 -0
- numdaplot/plots/figure/__init__.py +5 -0
- numdaplot/plots/figure/cell.py +95 -0
- numdaplot/plots/figure/figure.py +256 -0
- numdaplot/plots/figure/figure_drawing.py +99 -0
- numdaplot/plots/figure/figure_style.py +60 -0
- numdaplot/plots/figure/layout.py +71 -0
- numdaplot/plots/figure/placement.py +150 -0
- numdaplot/plots/layer_reading.py +166 -0
- numdaplot/plots/output/__init__.py +5 -0
- numdaplot/plots/output/image_saving.py +187 -0
- numdaplot/plots/output/plot_display.py +181 -0
- numdaplot/plots/output/shown_object.py +45 -0
- numdaplot/plots/overlay_checks.py +245 -0
- numdaplot/plots/plot.py +31 -0
- numdaplot/plots/plot_data.py +140 -0
- numdaplot/plots/plot_distribution_creation.py +237 -0
- numdaplot/plots/plot_output.py +124 -0
- numdaplot/plots/plot_overlays.py +273 -0
- numdaplot/plots/plot_overview_creation.py +195 -0
- numdaplot/plots/plot_series_creation.py +213 -0
- numdaplot/plots/style/__init__.py +5 -0
- numdaplot/plots/style/axis_settings.py +60 -0
- numdaplot/plots/style/color.py +168 -0
- numdaplot/plots/style/custom_color.py +65 -0
- numdaplot/plots/style/grid_lines.py +49 -0
- numdaplot/plots/style/image_options.py +71 -0
- numdaplot/plots/style/legend_position.py +149 -0
- numdaplot/plots/style/plot_style.py +136 -0
- numdaplot/plots/style/size.py +70 -0
- numdaplot/plots/style/size_unit.py +62 -0
- numdaplot/positions/__init__.py +5 -0
- numdaplot/positions/axis.py +54 -0
- numdaplot/positions/index.py +51 -0
- numdaplot/positions/range.py +90 -0
- numdaplot/positions/region.py +92 -0
- numdaplot/py.typed +0 -0
- numdaplot/ratios/__init__.py +5 -0
- numdaplot/ratios/fraction.py +40 -0
- numdaplot/ratios/measure.py +48 -0
- numdaplot/rules/__init__.py +5 -0
- numdaplot/rules/between.py +78 -0
- numdaplot/rules/bounds.py +83 -0
- numdaplot/rules/case.py +48 -0
- numdaplot/rules/contains.py +63 -0
- numdaplot/rules/equal.py +43 -0
- numdaplot/rules/greater.py +39 -0
- numdaplot/rules/greater_or_equal.py +38 -0
- numdaplot/rules/is_in.py +67 -0
- numdaplot/rules/is_missing.py +25 -0
- numdaplot/rules/is_present.py +25 -0
- numdaplot/rules/less.py +39 -0
- numdaplot/rules/less_or_equal.py +38 -0
- numdaplot/rules/not_equal.py +45 -0
- numdaplot/rules/rule.py +62 -0
- numdaplot/rules/rule_values.py +44 -0
- numdaplot/rules/value_rule.py +110 -0
- numdaplot/settings/__init__.py +5 -0
- numdaplot/settings/argument_types.py +327 -0
- numdaplot/settings/field_types.py +593 -0
- numdaplot/statistics/__init__.py +5 -0
- numdaplot/statistics/count.py +71 -0
- numdaplot/statistics/count_distinct.py +27 -0
- numdaplot/statistics/counted_missing.py +46 -0
- numdaplot/statistics/maximum.py +27 -0
- numdaplot/statistics/mean.py +27 -0
- numdaplot/statistics/median.py +27 -0
- numdaplot/statistics/minimum.py +27 -0
- numdaplot/statistics/most_frequent.py +27 -0
- numdaplot/statistics/most_frequent_count.py +27 -0
- numdaplot/statistics/quantile.py +61 -0
- numdaplot/statistics/standard_deviation.py +29 -0
- numdaplot/statistics/statistic.py +63 -0
- numdaplot/statistics/sum.py +27 -0
- numdaplot/tables/__init__.py +5 -0
- numdaplot/tables/aggregation/__init__.py +5 -0
- numdaplot/tables/aggregation/aggregated_frame.py +189 -0
- numdaplot/tables/aggregation/aggregation.py +97 -0
- numdaplot/tables/aggregation/calculation.py +123 -0
- numdaplot/tables/aggregation/result_column.py +108 -0
- numdaplot/tables/aggregation/row_groups.py +96 -0
- numdaplot/tables/aggregation/statistic_name.py +122 -0
- numdaplot/tables/columns/__init__.py +5 -0
- numdaplot/tables/columns/added_column.py +89 -0
- numdaplot/tables/columns/boolean_conversion.py +144 -0
- numdaplot/tables/columns/boolean_rule.py +59 -0
- numdaplot/tables/columns/bracket_end.py +50 -0
- numdaplot/tables/columns/bracket_names.py +346 -0
- numdaplot/tables/columns/bracketed_column.py +179 -0
- numdaplot/tables/columns/brackets.py +234 -0
- numdaplot/tables/columns/chosen_columns.py +55 -0
- numdaplot/tables/columns/column_choice.py +84 -0
- numdaplot/tables/columns/column_mode.py +64 -0
- numdaplot/tables/columns/column_names.py +186 -0
- numdaplot/tables/columns/conversion.py +103 -0
- numdaplot/tables/columns/converted_column.py +669 -0
- numdaplot/tables/columns/date_conversion.py +526 -0
- numdaplot/tables/columns/date_range.py +135 -0
- numdaplot/tables/columns/name_change.py +67 -0
- numdaplot/tables/columns/new_column.py +79 -0
- numdaplot/tables/columns/number_conversion.py +281 -0
- numdaplot/tables/columns/renamed_columns.py +60 -0
- numdaplot/tables/columns/renaming.py +81 -0
- numdaplot/tables/columns/text_conversion.py +70 -0
- numdaplot/tables/columns/time_conversion.py +313 -0
- numdaplot/tables/columns/time_zone_conversion.py +128 -0
- numdaplot/tables/conflict.py +68 -0
- numdaplot/tables/description/__init__.py +5 -0
- numdaplot/tables/description/described_frame.py +335 -0
- numdaplot/tables/description/description.py +155 -0
- numdaplot/tables/duplicates/__init__.py +5 -0
- numdaplot/tables/duplicates/deduplicated_frame.py +66 -0
- numdaplot/tables/duplicates/deduplication.py +88 -0
- numdaplot/tables/duplicates/keep.py +81 -0
- numdaplot/tables/files/__init__.py +5 -0
- numdaplot/tables/files/column_names.py +60 -0
- numdaplot/tables/files/csv_file.py +265 -0
- numdaplot/tables/files/csv_read_options.py +89 -0
- numdaplot/tables/files/csv_separator.py +41 -0
- numdaplot/tables/files/csv_write_options.py +79 -0
- numdaplot/tables/files/decimal_count.py +42 -0
- numdaplot/tables/files/encoding.py +82 -0
- numdaplot/tables/files/excel_file.py +171 -0
- numdaplot/tables/files/excel_read_options.py +79 -0
- numdaplot/tables/files/excel_sheet.py +50 -0
- numdaplot/tables/files/excel_time_cells.py +146 -0
- numdaplot/tables/files/excel_write_options.py +63 -0
- numdaplot/tables/files/file_access.py +152 -0
- numdaplot/tables/files/file_paths.py +106 -0
- numdaplot/tables/files/json_decimals.py +387 -0
- numdaplot/tables/files/json_file.py +203 -0
- numdaplot/tables/files/json_layout.py +63 -0
- numdaplot/tables/files/json_read_options.py +64 -0
- numdaplot/tables/files/json_write_options.py +71 -0
- numdaplot/tables/files/missing_texts.py +63 -0
- numdaplot/tables/files/optional_package.py +42 -0
- numdaplot/tables/files/pandas_backend.py +11 -0
- numdaplot/tables/files/parquet_file.py +91 -0
- numdaplot/tables/files/parquet_read_options.py +56 -0
- numdaplot/tables/files/sas_file.py +94 -0
- numdaplot/tables/files/sas_read_options.py +67 -0
- numdaplot/tables/files/stata_file.py +83 -0
- numdaplot/tables/files/stata_read_options.py +56 -0
- numdaplot/tables/files/xpt_read_options.py +65 -0
- numdaplot/tables/filtering/__init__.py +5 -0
- numdaplot/tables/filtering/checked_frame.py +60 -0
- numdaplot/tables/filtering/column_mask.py +71 -0
- numdaplot/tables/filtering/column_match.py +62 -0
- numdaplot/tables/filtering/condition.py +94 -0
- numdaplot/tables/filtering/filter.py +74 -0
- numdaplot/tables/filtering/filter_mode.py +67 -0
- numdaplot/tables/filtering/row_mask.py +152 -0
- numdaplot/tables/filtering/rule_moments.py +164 -0
- numdaplot/tables/frames/__init__.py +5 -0
- numdaplot/tables/frames/array_frame.py +95 -0
- numdaplot/tables/frames/cleaned_names.py +132 -0
- numdaplot/tables/frames/column.py +15 -0
- numdaplot/tables/frames/column_values.py +273 -0
- numdaplot/tables/frames/frame_equality.py +130 -0
- numdaplot/tables/frames/frame_normalization.py +459 -0
- numdaplot/tables/frames/named_column_errors.py +85 -0
- numdaplot/tables/frames/pandas_decimals.py +113 -0
- numdaplot/tables/frames/region_positions.py +113 -0
- numdaplot/tables/frames/table_text.py +222 -0
- numdaplot/tables/frames/time_columns.py +345 -0
- numdaplot/tables/frames/time_range_errors.py +117 -0
- numdaplot/tables/frames/time_zones.py +271 -0
- numdaplot/tables/joining/__init__.py +5 -0
- numdaplot/tables/joining/join.py +110 -0
- numdaplot/tables/joining/join_keys.py +367 -0
- numdaplot/tables/joining/join_mode.py +93 -0
- numdaplot/tables/joining/join_relation.py +149 -0
- numdaplot/tables/joining/join_suffixes.py +71 -0
- numdaplot/tables/joining/joined_frame.py +166 -0
- numdaplot/tables/joining/joined_names.py +107 -0
- numdaplot/tables/joining/joined_rows.py +235 -0
- numdaplot/tables/joining/key_types.py +57 -0
- numdaplot/tables/joining/relation.py +78 -0
- numdaplot/tables/missing/__init__.py +5 -0
- numdaplot/tables/missing/missing_count.py +59 -0
- numdaplot/tables/missing/missing_counts.py +214 -0
- numdaplot/tables/missing/missing_drop.py +98 -0
- numdaplot/tables/missing/missing_mode.py +63 -0
- numdaplot/tables/missing/missing_ratio.py +71 -0
- numdaplot/tables/missing/missing_removal.py +257 -0
- numdaplot/tables/missing/missing_summary.py +174 -0
- numdaplot/tables/missing/ratio_comparison.py +70 -0
- numdaplot/tables/pivot/__init__.py +5 -0
- numdaplot/tables/pivot/pivot_table.py +104 -0
- numdaplot/tables/pivot/pivoted_frame.py +244 -0
- numdaplot/tables/preview/__init__.py +5 -0
- numdaplot/tables/preview/notebook_display.py +238 -0
- numdaplot/tables/preview/preview.py +100 -0
- numdaplot/tables/preview/preview_rows.py +55 -0
- numdaplot/tables/preview/shown_columns.py +62 -0
- numdaplot/tables/preview/side.py +82 -0
- numdaplot/tables/sorting/__init__.py +5 -0
- numdaplot/tables/sorting/sort_key.py +71 -0
- numdaplot/tables/sorting/sorted_frame.py +81 -0
- numdaplot/tables/sorting/sorting.py +82 -0
- numdaplot/tables/table.py +71 -0
- numdaplot/tables/table_calculation.py +172 -0
- numdaplot/tables/table_columns.py +214 -0
- numdaplot/tables/table_conversion.py +351 -0
- numdaplot/tables/table_data.py +321 -0
- numdaplot/tables/table_display.py +56 -0
- numdaplot/tables/table_joining.py +80 -0
- numdaplot/tables/table_layout.py +105 -0
- numdaplot/tables/table_missing.py +146 -0
- numdaplot/tables/table_reading.py +451 -0
- numdaplot/tables/table_refusals.py +295 -0
- numdaplot/tables/table_selection.py +163 -0
- numdaplot/tables/table_writing.py +269 -0
- numdaplot-0.1.0.dist-info/METADATA +176 -0
- numdaplot-0.1.0.dist-info/RECORD +474 -0
- numdaplot-0.1.0.dist-info/WHEEL +4 -0
- numdaplot-0.1.0.dist-info/licenses/LICENSE +28 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Whether Count counts the missing values.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from enum import Enum, auto
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CountedMissing(Enum):
|
|
11
|
+
"""
|
|
12
|
+
Whether ``Count`` counts the missing values.
|
|
13
|
+
|
|
14
|
+
.. versionadded:: 0.1.0
|
|
15
|
+
|
|
16
|
+
Examples
|
|
17
|
+
--------
|
|
18
|
+
>>> import numdaplot as ndp
|
|
19
|
+
>>> answers = ndp.Array.from_list([4.0, None, 2.0])
|
|
20
|
+
>>> answers.compute(ndp.Count(missing=ndp.CountedMissing.INCLUDED)).to_value()
|
|
21
|
+
3
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
EXCLUDED = auto()
|
|
25
|
+
"""
|
|
26
|
+
Only the present values are counted. Default value.
|
|
27
|
+
|
|
28
|
+
Examples
|
|
29
|
+
--------
|
|
30
|
+
>>> import numdaplot as ndp
|
|
31
|
+
>>> answers = ndp.Array.from_list([4.0, None, 2.0])
|
|
32
|
+
>>> answers.compute(ndp.Count(missing=ndp.CountedMissing.EXCLUDED)).to_value()
|
|
33
|
+
2
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
INCLUDED = auto()
|
|
37
|
+
"""
|
|
38
|
+
Every value is counted, missing or not, which gives the number of rows of a column.
|
|
39
|
+
|
|
40
|
+
Examples
|
|
41
|
+
--------
|
|
42
|
+
>>> import numdaplot as ndp
|
|
43
|
+
>>> answers = ndp.Array.from_list([4.0, None, 2.0])
|
|
44
|
+
>>> answers.compute(ndp.Count(missing=ndp.CountedMissing.INCLUDED)).to_value()
|
|
45
|
+
3
|
|
46
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Largest value statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.statistics.statistic import Statistic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class Max(Statistic):
|
|
14
|
+
"""
|
|
15
|
+
Largest value.
|
|
16
|
+
|
|
17
|
+
Missing values are ignored.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
>>> import numdaplot as ndp
|
|
24
|
+
>>> prices = ndp.Array.from_list([12.0, None, 30.0])
|
|
25
|
+
>>> prices.compute(ndp.Max()).to_value()
|
|
26
|
+
30.0
|
|
27
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Arithmetic mean of the values statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.statistics.statistic import Statistic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class Mean(Statistic):
|
|
14
|
+
"""
|
|
15
|
+
Arithmetic mean of the values.
|
|
16
|
+
|
|
17
|
+
Missing values are ignored.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
>>> import numdaplot as ndp
|
|
24
|
+
>>> prices = ndp.Array.from_list([10.0, None, 30.0])
|
|
25
|
+
>>> prices.compute(ndp.Mean()).to_value()
|
|
26
|
+
20.0
|
|
27
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Median of the values, the middle value once sorted statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.statistics.statistic import Statistic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class Median(Statistic):
|
|
14
|
+
"""
|
|
15
|
+
Median of the values, the middle value once sorted.
|
|
16
|
+
|
|
17
|
+
It equals ``Quantile(0.5)``. Missing values are ignored.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
>>> import numdaplot as ndp
|
|
24
|
+
>>> salaries = ndp.Array.from_list([1800, 2000, 9000])
|
|
25
|
+
>>> salaries.compute(ndp.Median()).to_value()
|
|
26
|
+
2000.0
|
|
27
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Smallest value statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.statistics.statistic import Statistic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class Min(Statistic):
|
|
14
|
+
"""
|
|
15
|
+
Smallest value.
|
|
16
|
+
|
|
17
|
+
Missing values are ignored.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
>>> import numdaplot as ndp
|
|
24
|
+
>>> cities = ndp.Array.from_list(["Pau", "Lyon", "Paris"])
|
|
25
|
+
>>> cities.compute(ndp.Min()).to_value()
|
|
26
|
+
'Lyon'
|
|
27
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Value that appears the most often statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.statistics.statistic import Statistic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class MostFrequent(Statistic):
|
|
14
|
+
"""
|
|
15
|
+
Value that appears the most often.
|
|
16
|
+
|
|
17
|
+
Works on any type, text included. Missing values are ignored.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
>>> import numdaplot as ndp
|
|
24
|
+
>>> sizes = ndp.Array.from_list(["M", "L", "M"])
|
|
25
|
+
>>> sizes.compute(ndp.MostFrequent()).to_value()
|
|
26
|
+
'M'
|
|
27
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Number of times the most frequent value appears statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.statistics.statistic import Statistic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class MostFrequentCount(Statistic):
|
|
14
|
+
"""
|
|
15
|
+
Number of times the most frequent value appears.
|
|
16
|
+
|
|
17
|
+
Works on any type, text included.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
>>> import numdaplot as ndp
|
|
24
|
+
>>> sizes = ndp.Array.from_list(["M", "L", "M"])
|
|
25
|
+
>>> sizes.compute(ndp.MostFrequentCount()).to_value()
|
|
26
|
+
2
|
|
27
|
+
"""
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Quantile statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.ratios.fraction import require_fraction
|
|
10
|
+
from numdaplot.settings.field_types import require_field_types
|
|
11
|
+
from numdaplot.statistics.statistic import Statistic
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class Quantile(Statistic):
|
|
16
|
+
"""
|
|
17
|
+
Value below which a given fraction of the values lies.
|
|
18
|
+
|
|
19
|
+
``Quantile(0.9)`` on salaries gives the salary below which 90 % of people are,
|
|
20
|
+
and ``Quantile(0.5)`` is the median. Missing values are ignored.
|
|
21
|
+
|
|
22
|
+
.. versionadded:: 0.1.0
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
fraction
|
|
27
|
+
Fraction of the values that lie below the result, between 0 and 1 included.
|
|
28
|
+
|
|
29
|
+
Raises
|
|
30
|
+
------
|
|
31
|
+
InvalidTypeError
|
|
32
|
+
When a setting is not of the type its annotation names.
|
|
33
|
+
InvalidFractionError
|
|
34
|
+
When ``fraction`` is lower than 0, greater than 1 or NaN.
|
|
35
|
+
|
|
36
|
+
Examples
|
|
37
|
+
--------
|
|
38
|
+
>>> import numdaplot as ndp
|
|
39
|
+
>>> salaries = ndp.Array.from_list([1000, 2000, 3000, 4000, 5000])
|
|
40
|
+
>>> salaries.compute(ndp.Quantile(0.9)).to_value()
|
|
41
|
+
4600.0
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
fraction: float
|
|
45
|
+
|
|
46
|
+
def __post_init__(self) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Check that the fraction is between 0 and 1.
|
|
49
|
+
|
|
50
|
+
.. versionadded:: 0.1.0
|
|
51
|
+
|
|
52
|
+
Raises
|
|
53
|
+
------
|
|
54
|
+
InvalidTypeError
|
|
55
|
+
When a setting is not of the type its annotation names.
|
|
56
|
+
InvalidFractionError
|
|
57
|
+
When ``fraction`` is lower than 0, greater than 1 or NaN.
|
|
58
|
+
"""
|
|
59
|
+
require_field_types(self)
|
|
60
|
+
|
|
61
|
+
require_fraction(self.fraction)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Standard deviation statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.statistics.statistic import Statistic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class StandardDeviation(Statistic):
|
|
14
|
+
"""
|
|
15
|
+
Standard deviation of the values, how far they spread around the mean.
|
|
16
|
+
|
|
17
|
+
``[10, 10, 10]`` gives 0, while ``[0, 10, 20]`` gives about 8.2. It is the population standard
|
|
18
|
+
deviation, divided by the number of values as in numpy, not by that number minus one as in pandas.
|
|
19
|
+
Missing values are ignored.
|
|
20
|
+
|
|
21
|
+
.. versionadded:: 0.1.0
|
|
22
|
+
|
|
23
|
+
Examples
|
|
24
|
+
--------
|
|
25
|
+
>>> import numdaplot as ndp
|
|
26
|
+
>>> grades = ndp.Array.from_list([8, 12])
|
|
27
|
+
>>> grades.compute(ndp.StandardDeviation()).to_value()
|
|
28
|
+
2.0
|
|
29
|
+
"""
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base class of every statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from numdaplot.errors.refused_operation_error import RefusedOperationError
|
|
8
|
+
|
|
9
|
+
CONSTRUCTOR_OPERATION = "Creating a Statistic with ndp.Statistic()"
|
|
10
|
+
CONSTRUCTOR_ALTERNATIVE = "a statistic such as ndp.Mean"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Statistic:
|
|
14
|
+
"""
|
|
15
|
+
Base class of every statistic, a single result computed from a set of values.
|
|
16
|
+
|
|
17
|
+
A statistic is immutable and checks its settings when it is created.
|
|
18
|
+
|
|
19
|
+
Only its subclasses are created: calling ``ndp.Statistic()`` raises ``RefusedOperationError``.
|
|
20
|
+
|
|
21
|
+
Every statistic, passed to ``Array.compute``, ``Calculation`` and ``Description``:
|
|
22
|
+
|
|
23
|
+
|Statistic|What it computes|Example|
|
|
24
|
+
|---|---|---|
|
|
25
|
+
|``Count``|Number of values, without the missing ones by default|``ndp.Count()``|
|
|
26
|
+
|``CountDistinct``|Number of distinct values that are not missing|``ndp.CountDistinct()``|
|
|
27
|
+
|``Sum``|Sum of the values|``ndp.Sum()``|
|
|
28
|
+
|``Mean``|Arithmetic mean of the values|``ndp.Mean()``|
|
|
29
|
+
|``Median``|Median of the values, the middle value once sorted|``ndp.Median()``|
|
|
30
|
+
|``Min``|Smallest value|``ndp.Min()``|
|
|
31
|
+
|``Max``|Largest value|``ndp.Max()``|
|
|
32
|
+
|``StandardDeviation``|How far the values spread around the mean|``ndp.StandardDeviation()``|
|
|
33
|
+
|``Quantile``|Value below which a given fraction of the values lies|``ndp.Quantile(0.9)``|
|
|
34
|
+
|``MostFrequent``|Value that appears the most often|``ndp.MostFrequent()``|
|
|
35
|
+
|``MostFrequentCount``|Number of times the most frequent value appears|``ndp.MostFrequentCount()``|
|
|
36
|
+
|
|
37
|
+
.. versionadded:: 0.1.0
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
>>> import numdaplot as ndp
|
|
42
|
+
>>> prices = ndp.Array.from_list([10.0, 30.0])
|
|
43
|
+
>>> for statistic in [ndp.Min(), ndp.Mean(), ndp.Max()]:
|
|
44
|
+
... print(prices.compute(statistic).to_value())
|
|
45
|
+
10.0
|
|
46
|
+
20.0
|
|
47
|
+
30.0
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self) -> None:
|
|
51
|
+
"""
|
|
52
|
+
Refuse the creation of the base class itself, and let a subclass be created.
|
|
53
|
+
|
|
54
|
+
.. versionadded:: 0.1.0
|
|
55
|
+
|
|
56
|
+
Raises
|
|
57
|
+
------
|
|
58
|
+
RefusedOperationError
|
|
59
|
+
When the created object is a Statistic and not one of its subclasses.
|
|
60
|
+
"""
|
|
61
|
+
created_class = type(self)
|
|
62
|
+
if created_class is Statistic:
|
|
63
|
+
raise RefusedOperationError(CONSTRUCTOR_OPERATION, CONSTRUCTOR_ALTERNATIVE)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sum of the values statistic.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.statistics.statistic import Statistic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class Sum(Statistic):
|
|
14
|
+
"""
|
|
15
|
+
Sum of the values.
|
|
16
|
+
|
|
17
|
+
Missing values are ignored.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
>>> import numdaplot as ndp
|
|
24
|
+
>>> amounts = ndp.Array.from_list([10.5, None, 4.5])
|
|
25
|
+
>>> amounts.compute(ndp.Sum()).to_value()
|
|
26
|
+
15.0
|
|
27
|
+
"""
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Aggregation of the rows of a Table.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
import numpy
|
|
10
|
+
import pandas
|
|
11
|
+
from numpy.typing import NDArray
|
|
12
|
+
|
|
13
|
+
from numdaplot.statistics.statistic import Statistic
|
|
14
|
+
from numdaplot.tables.aggregation.aggregation import Aggregation
|
|
15
|
+
from numdaplot.tables.aggregation.calculation import find_result_name
|
|
16
|
+
from numdaplot.tables.aggregation.result_column import build_result_column, compute_cell
|
|
17
|
+
from numdaplot.tables.aggregation.row_groups import find_row_groups
|
|
18
|
+
from numdaplot.tables.columns.column_names import require_known_columns
|
|
19
|
+
from numdaplot.tables.frames.column import Column
|
|
20
|
+
from numdaplot.tables.frames.column_values import find_column_missing, read_present_values
|
|
21
|
+
from numdaplot.tables.frames.named_column_errors import NamedColumnErrors
|
|
22
|
+
from numdaplot.tables.frames.time_zones import attribute_source_time_zone
|
|
23
|
+
|
|
24
|
+
FIRST_ROW = 0
|
|
25
|
+
ROW_POSITION_DTYPE = numpy.int64
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def aggregate_frame(frame: pandas.DataFrame, aggregation: Aggregation) -> pandas.DataFrame:
|
|
29
|
+
"""
|
|
30
|
+
Return the statistics of the whole Table, or of each group of rows.
|
|
31
|
+
|
|
32
|
+
.. versionadded:: 0.1.0
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
frame
|
|
37
|
+
The columns of a Table.
|
|
38
|
+
aggregation
|
|
39
|
+
The statistics and the group columns.
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
pandas.DataFrame
|
|
44
|
+
One row per group, sorted by group values with missing values last, or a single row.
|
|
45
|
+
The group columns come first, then one column per calculation.
|
|
46
|
+
|
|
47
|
+
Raises
|
|
48
|
+
------
|
|
49
|
+
ColumnNotFoundError
|
|
50
|
+
When a calculation or a group names a column the Table does not have.
|
|
51
|
+
IncompatibleTypesError
|
|
52
|
+
When a statistic does not apply to the type of its column.
|
|
53
|
+
|
|
54
|
+
Examples
|
|
55
|
+
--------
|
|
56
|
+
>>> import pandas
|
|
57
|
+
>>> import numdaplot as ndp
|
|
58
|
+
>>> from numdaplot.tables.aggregation.aggregated_frame import aggregate_frame
|
|
59
|
+
>>> frame = pandas.DataFrame({"city": ["Pau", "Lyon", "Pau"], "price": [1.0, 2.0, 3.0]})
|
|
60
|
+
>>> total = ndp.Calculation(column="price", function=ndp.Sum())
|
|
61
|
+
>>> aggregate_frame(frame, ndp.Aggregation(calculations=[total], group_by=["city"]))
|
|
62
|
+
city price_sum
|
|
63
|
+
0 Lyon 2.0
|
|
64
|
+
1 Pau 4.0
|
|
65
|
+
"""
|
|
66
|
+
column_names = [str(column_name) for column_name in frame.columns]
|
|
67
|
+
calculation_columns = [calculation.column for calculation in aggregation.calculations]
|
|
68
|
+
require_known_columns(calculation_columns, column_names)
|
|
69
|
+
group_by = aggregation.group_by
|
|
70
|
+
if group_by is not None:
|
|
71
|
+
require_known_columns(group_by, column_names)
|
|
72
|
+
|
|
73
|
+
row_groups = find_row_groups(frame, group_by)
|
|
74
|
+
result_columns = dict[str, Column]()
|
|
75
|
+
if group_by is not None:
|
|
76
|
+
key_columns = take_group_keys(frame, group_by, row_groups)
|
|
77
|
+
result_columns.update(key_columns)
|
|
78
|
+
|
|
79
|
+
for calculation in aggregation.calculations:
|
|
80
|
+
result_name = find_result_name(calculation)
|
|
81
|
+
column = frame[calculation.column]
|
|
82
|
+
result_column = compute_group_results(column, calculation.function, row_groups)
|
|
83
|
+
result_columns[result_name] = result_column
|
|
84
|
+
|
|
85
|
+
group_count = len(row_groups)
|
|
86
|
+
group_numbers = pandas.RangeIndex(group_count)
|
|
87
|
+
aggregated_frame = pandas.DataFrame(result_columns, index=group_numbers)
|
|
88
|
+
|
|
89
|
+
return aggregated_frame
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def take_group_keys(frame: pandas.DataFrame, group_by: list[str], row_groups: list[NDArray[Any]]) -> dict[str, Column]:
|
|
93
|
+
"""
|
|
94
|
+
Return the values of the group columns for each group, taken from its first row.
|
|
95
|
+
|
|
96
|
+
.. versionadded:: 0.1.0
|
|
97
|
+
|
|
98
|
+
Parameters
|
|
99
|
+
----------
|
|
100
|
+
frame
|
|
101
|
+
The columns of a Table.
|
|
102
|
+
group_by
|
|
103
|
+
The names of the group columns.
|
|
104
|
+
row_groups
|
|
105
|
+
The rows of each group.
|
|
106
|
+
|
|
107
|
+
Returns
|
|
108
|
+
-------
|
|
109
|
+
dict[str, Column]
|
|
110
|
+
One column per group column, one row per group, numbered from 0.
|
|
111
|
+
|
|
112
|
+
Examples
|
|
113
|
+
--------
|
|
114
|
+
>>> import numpy
|
|
115
|
+
>>> import pandas
|
|
116
|
+
>>> from numdaplot.tables.aggregation.aggregated_frame import take_group_keys
|
|
117
|
+
>>> frame = pandas.DataFrame({"city": ["Pau", "Lyon", "Pau"]})
|
|
118
|
+
>>> take_group_keys(frame, ["city"], [numpy.array([1]), numpy.array([0, 2])])["city"].tolist()
|
|
119
|
+
['Lyon', 'Pau']
|
|
120
|
+
"""
|
|
121
|
+
first_row_list = [row_group[FIRST_ROW] for row_group in row_groups]
|
|
122
|
+
first_rows = numpy.array(first_row_list, dtype=ROW_POSITION_DTYPE)
|
|
123
|
+
key_columns = dict[str, Column]()
|
|
124
|
+
|
|
125
|
+
for column_name in group_by:
|
|
126
|
+
column = frame[column_name]
|
|
127
|
+
first_values = column.iloc[first_rows]
|
|
128
|
+
key_column = first_values.reset_index(drop=True)
|
|
129
|
+
key_columns[column_name] = key_column
|
|
130
|
+
|
|
131
|
+
return key_columns
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def compute_group_results(column: Column, statistic: Statistic, row_groups: list[NDArray[Any]]) -> Column:
|
|
135
|
+
"""
|
|
136
|
+
Return a statistic of the values of a column, for each group of rows, missing values left out unless counted.
|
|
137
|
+
|
|
138
|
+
.. versionadded:: 0.1.0
|
|
139
|
+
|
|
140
|
+
Parameters
|
|
141
|
+
----------
|
|
142
|
+
column
|
|
143
|
+
A Table column.
|
|
144
|
+
statistic
|
|
145
|
+
Any statistic of numdaplot.
|
|
146
|
+
row_groups
|
|
147
|
+
The rows of each group.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
Column
|
|
152
|
+
One result per group, missing for a group without present value when the statistic needs one.
|
|
153
|
+
|
|
154
|
+
Raises
|
|
155
|
+
------
|
|
156
|
+
IncompatibleTypesError
|
|
157
|
+
When the statistic does not apply to the type of the column.
|
|
158
|
+
|
|
159
|
+
Examples
|
|
160
|
+
--------
|
|
161
|
+
>>> import numpy
|
|
162
|
+
>>> import pandas
|
|
163
|
+
>>> import numdaplot as ndp
|
|
164
|
+
>>> from numdaplot.tables.aggregation.aggregated_frame import compute_group_results
|
|
165
|
+
>>> column = pandas.Series([1.0, None, 3.0])
|
|
166
|
+
>>> compute_group_results(column, ndp.Mean(), [numpy.array([1]), numpy.array([0, 2])]).tolist()
|
|
167
|
+
[nan, 2.0]
|
|
168
|
+
"""
|
|
169
|
+
missing = find_column_missing(column)
|
|
170
|
+
present = ~missing
|
|
171
|
+
present_values = read_present_values(column)
|
|
172
|
+
present_counts = numpy.cumsum(present)
|
|
173
|
+
value_positions = present_counts - 1
|
|
174
|
+
results = list[NDArray[Any] | None]()
|
|
175
|
+
|
|
176
|
+
with NamedColumnErrors(column):
|
|
177
|
+
for row_group in row_groups:
|
|
178
|
+
group_present = present[row_group]
|
|
179
|
+
present_rows = row_group[group_present]
|
|
180
|
+
group_value_positions = value_positions[present_rows]
|
|
181
|
+
group_values = present_values[group_value_positions]
|
|
182
|
+
group_size = len(row_group)
|
|
183
|
+
result = compute_cell(group_values, statistic, group_size)
|
|
184
|
+
results.append(result)
|
|
185
|
+
|
|
186
|
+
utc_results = build_result_column(results)
|
|
187
|
+
result_column = attribute_source_time_zone(utc_results, column)
|
|
188
|
+
|
|
189
|
+
return result_column
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Settings of the aggregation of the rows of a Table.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.errors.empty_list_error import EmptyListError
|
|
10
|
+
from numdaplot.settings.field_types import require_field_types
|
|
11
|
+
from numdaplot.tables.aggregation.calculation import Calculation, find_result_name
|
|
12
|
+
from numdaplot.tables.columns.column_names import require_column_names, require_unique_names
|
|
13
|
+
|
|
14
|
+
CALCULATION_ITEM_NAME = "calculation"
|
|
15
|
+
GROUP_COLUMN_ITEM_NAME = "group column"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class Aggregation:
|
|
20
|
+
"""
|
|
21
|
+
Statistics computed on the whole Table or on each group of rows, used by ``Table.aggregate``.
|
|
22
|
+
|
|
23
|
+
.. versionadded:: 0.1.0
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
calculations
|
|
28
|
+
The statistics to compute, at least one. The aggregation keeps its own copy of the list.
|
|
29
|
+
group_by
|
|
30
|
+
The names of the columns whose values form the groups: one result row per combination
|
|
31
|
+
of values. The whole Table gives a single row when omitted.
|
|
32
|
+
|
|
33
|
+
Raises
|
|
34
|
+
------
|
|
35
|
+
InvalidTypeError
|
|
36
|
+
When a setting is not of the type its annotation names.
|
|
37
|
+
EmptyListError
|
|
38
|
+
When ``calculations`` or ``group_by`` is an empty list.
|
|
39
|
+
InvalidColumnNameError
|
|
40
|
+
When a group column name is an empty text.
|
|
41
|
+
DuplicateColumnError
|
|
42
|
+
When a name appears twice among the group columns and the result names.
|
|
43
|
+
|
|
44
|
+
Examples
|
|
45
|
+
--------
|
|
46
|
+
>>> import numdaplot as ndp
|
|
47
|
+
>>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
|
|
48
|
+
>>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
|
|
49
|
+
>>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
|
|
50
|
+
>>> average_price = ndp.Calculation(column="price", function=ndp.Mean())
|
|
51
|
+
>>> sales.aggregate(ndp.Aggregation(calculations=[average_price], group_by=["city"]))
|
|
52
|
+
city price_mean
|
|
53
|
+
TEXT FLOAT64
|
|
54
|
+
0 Lyon 80.0
|
|
55
|
+
1 Paris 135.0
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
calculations: list[Calculation]
|
|
59
|
+
group_by: list[str] | None = None
|
|
60
|
+
|
|
61
|
+
def __post_init__(self) -> None:
|
|
62
|
+
"""
|
|
63
|
+
Check the lists and replace them with copies that only the aggregation holds.
|
|
64
|
+
|
|
65
|
+
.. versionadded:: 0.1.0
|
|
66
|
+
|
|
67
|
+
Raises
|
|
68
|
+
------
|
|
69
|
+
InvalidTypeError
|
|
70
|
+
When a setting is not of the type its annotation names.
|
|
71
|
+
EmptyListError
|
|
72
|
+
When ``calculations`` or ``group_by`` is an empty list.
|
|
73
|
+
InvalidColumnNameError
|
|
74
|
+
When a group column name is an empty text.
|
|
75
|
+
DuplicateColumnError
|
|
76
|
+
When a name appears twice among the group columns and the result names.
|
|
77
|
+
"""
|
|
78
|
+
require_field_types(self)
|
|
79
|
+
|
|
80
|
+
if self.calculations == []:
|
|
81
|
+
raise EmptyListError(CALCULATION_ITEM_NAME)
|
|
82
|
+
|
|
83
|
+
if self.group_by == []:
|
|
84
|
+
raise EmptyListError(GROUP_COLUMN_ITEM_NAME)
|
|
85
|
+
|
|
86
|
+
calculations_copy = list(self.calculations)
|
|
87
|
+
object.__setattr__(self, "calculations", calculations_copy)
|
|
88
|
+
output_names = list[str]()
|
|
89
|
+
if self.group_by is not None:
|
|
90
|
+
require_column_names(self.group_by)
|
|
91
|
+
group_by_copy = list(self.group_by)
|
|
92
|
+
object.__setattr__(self, "group_by", group_by_copy)
|
|
93
|
+
output_names.extend(group_by_copy)
|
|
94
|
+
|
|
95
|
+
result_names = [find_result_name(calculation) for calculation in calculations_copy]
|
|
96
|
+
output_names.extend(result_names)
|
|
97
|
+
require_unique_names(output_names)
|