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,335 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Description of the columns of a Table.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import UTC, datetime
|
|
8
|
+
from typing import Any
|
|
9
|
+
from zoneinfo import ZoneInfo
|
|
10
|
+
|
|
11
|
+
import numpy
|
|
12
|
+
import pandas
|
|
13
|
+
from numpy.typing import NDArray
|
|
14
|
+
|
|
15
|
+
from numdaplot.arrays.conversion.python_values import to_python_list
|
|
16
|
+
from numdaplot.data_types.numpy_mapping import from_numpy_dtype, to_numpy_dtype
|
|
17
|
+
from numdaplot.data_types.type import Type
|
|
18
|
+
from numdaplot.data_types.value_family import ValueFamily, find_family
|
|
19
|
+
from numdaplot.dates.time_zone import TimeZone
|
|
20
|
+
from numdaplot.errors.duplicate_column_error import DuplicateColumnError
|
|
21
|
+
from numdaplot.errors.incompatible_types_error import IncompatibleTypesError
|
|
22
|
+
from numdaplot.statistics.statistic import Statistic
|
|
23
|
+
from numdaplot.tables.aggregation.result_column import build_result_column, compute_cell
|
|
24
|
+
from numdaplot.tables.aggregation.statistic_name import name_statistic
|
|
25
|
+
from numdaplot.tables.columns.column_names import require_known_columns
|
|
26
|
+
from numdaplot.tables.description.description import DEFAULT_FUNCTIONS, Description
|
|
27
|
+
from numdaplot.tables.frames.column import Column
|
|
28
|
+
from numdaplot.tables.frames.column_values import build_column, find_column_type, read_present_values
|
|
29
|
+
from numdaplot.tables.frames.time_zones import attribute_source_time_zone, find_column_time_zone
|
|
30
|
+
|
|
31
|
+
STATISTIC_COLUMN_NAME = "statistic"
|
|
32
|
+
SINGLE_FAMILY_COUNT = 1
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def describe_frame(frame: pandas.DataFrame, description: Description) -> pandas.DataFrame:
|
|
36
|
+
"""
|
|
37
|
+
Return statistics of columns of a Table, one row per statistic and one column per described column.
|
|
38
|
+
|
|
39
|
+
.. versionadded:: 0.1.0
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
frame
|
|
44
|
+
The columns of a Table.
|
|
45
|
+
description
|
|
46
|
+
The statistics and the columns to describe.
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
50
|
+
pandas.DataFrame
|
|
51
|
+
A first ``statistic`` column naming each statistic, then one column per described column.
|
|
52
|
+
A cell is missing when the statistic does not apply to the column or finds no value.
|
|
53
|
+
|
|
54
|
+
Raises
|
|
55
|
+
------
|
|
56
|
+
ColumnNotFoundError
|
|
57
|
+
When a described column does not exist.
|
|
58
|
+
DuplicateColumnError
|
|
59
|
+
When a described column is named ``statistic``.
|
|
60
|
+
|
|
61
|
+
Examples
|
|
62
|
+
--------
|
|
63
|
+
>>> import pandas
|
|
64
|
+
>>> import numdaplot as ndp
|
|
65
|
+
>>> from numdaplot.tables.description.described_frame import describe_frame
|
|
66
|
+
>>> frame = pandas.DataFrame({"price": [1.0, 3.0]})
|
|
67
|
+
>>> describe_frame(frame, ndp.Description(functions=[ndp.Count(), ndp.Mean()]))
|
|
68
|
+
statistic price
|
|
69
|
+
0 count_excluded 2.0
|
|
70
|
+
1 mean 2.0
|
|
71
|
+
"""
|
|
72
|
+
functions = list[Statistic](DEFAULT_FUNCTIONS)
|
|
73
|
+
if description.functions is not None:
|
|
74
|
+
functions = description.functions
|
|
75
|
+
|
|
76
|
+
described_names = find_described_columns(frame, description)
|
|
77
|
+
statistic_names = [name_statistic(function) for function in functions]
|
|
78
|
+
text_dtype = to_numpy_dtype(Type.TEXT)
|
|
79
|
+
statistic_values = numpy.array(statistic_names, dtype=text_dtype)
|
|
80
|
+
statistic_column = build_column(statistic_values)
|
|
81
|
+
described_columns = {STATISTIC_COLUMN_NAME: statistic_column}
|
|
82
|
+
|
|
83
|
+
for column_name in described_names:
|
|
84
|
+
column = frame[column_name]
|
|
85
|
+
described_column = describe_column(column, functions)
|
|
86
|
+
described_columns[column_name] = described_column
|
|
87
|
+
|
|
88
|
+
function_count = len(functions)
|
|
89
|
+
row_numbers = pandas.RangeIndex(function_count)
|
|
90
|
+
described_frame = pandas.DataFrame(described_columns, index=row_numbers)
|
|
91
|
+
|
|
92
|
+
return described_frame
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def find_described_columns(frame: pandas.DataFrame, description: Description) -> list[str]:
|
|
96
|
+
"""
|
|
97
|
+
Return the names of the columns to describe.
|
|
98
|
+
|
|
99
|
+
.. versionadded:: 0.1.0
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
frame
|
|
104
|
+
The columns of a Table.
|
|
105
|
+
description
|
|
106
|
+
The settings of the description.
|
|
107
|
+
|
|
108
|
+
Returns
|
|
109
|
+
-------
|
|
110
|
+
list[str]
|
|
111
|
+
The given names, or every number column in the order of the Table.
|
|
112
|
+
|
|
113
|
+
Raises
|
|
114
|
+
------
|
|
115
|
+
ColumnNotFoundError
|
|
116
|
+
When a given column does not exist.
|
|
117
|
+
DuplicateColumnError
|
|
118
|
+
When a described column is named ``statistic``.
|
|
119
|
+
|
|
120
|
+
Examples
|
|
121
|
+
--------
|
|
122
|
+
>>> import pandas
|
|
123
|
+
>>> import numdaplot as ndp
|
|
124
|
+
>>> from numdaplot.tables.description.described_frame import find_described_columns
|
|
125
|
+
>>> frame = pandas.DataFrame({"city": pandas.array(["Pau"], dtype="string"), "price": [1.5]})
|
|
126
|
+
>>> find_described_columns(frame, ndp.Description())
|
|
127
|
+
['price']
|
|
128
|
+
"""
|
|
129
|
+
column_names = [str(column_name) for column_name in frame.columns]
|
|
130
|
+
described_names = list[str]()
|
|
131
|
+
if description.columns is not None:
|
|
132
|
+
require_known_columns(description.columns, column_names)
|
|
133
|
+
described_names = description.columns
|
|
134
|
+
else:
|
|
135
|
+
described_names = find_number_columns(frame)
|
|
136
|
+
|
|
137
|
+
if STATISTIC_COLUMN_NAME in described_names:
|
|
138
|
+
raise DuplicateColumnError(STATISTIC_COLUMN_NAME)
|
|
139
|
+
|
|
140
|
+
return described_names
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def find_number_columns(frame: pandas.DataFrame) -> list[str]:
|
|
144
|
+
"""
|
|
145
|
+
Return the names of the columns holding numbers.
|
|
146
|
+
|
|
147
|
+
.. versionadded:: 0.1.0
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
frame
|
|
152
|
+
The columns of a Table.
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
list[str]
|
|
157
|
+
The names of the integer and decimal columns, in order.
|
|
158
|
+
|
|
159
|
+
Examples
|
|
160
|
+
--------
|
|
161
|
+
>>> import pandas
|
|
162
|
+
>>> from numdaplot.tables.description.described_frame import find_number_columns
|
|
163
|
+
>>> find_number_columns(pandas.DataFrame({"price": [1.5], "paid": pandas.array([True], dtype="boolean")}))
|
|
164
|
+
['price']
|
|
165
|
+
"""
|
|
166
|
+
number_names = list[str]()
|
|
167
|
+
|
|
168
|
+
for column_name in frame.columns:
|
|
169
|
+
column = frame[column_name]
|
|
170
|
+
column_type = find_column_type(column)
|
|
171
|
+
column_family = find_family(column_type)
|
|
172
|
+
if column_family == ValueFamily.NUMBER:
|
|
173
|
+
number_name = str(column_name)
|
|
174
|
+
number_names.append(number_name)
|
|
175
|
+
|
|
176
|
+
return number_names
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def describe_column(column: Column, functions: list[Statistic]) -> Column:
|
|
180
|
+
"""
|
|
181
|
+
Return the statistics of one column, missing where a statistic does not apply or finds no value.
|
|
182
|
+
|
|
183
|
+
.. versionadded:: 0.1.0
|
|
184
|
+
|
|
185
|
+
Parameters
|
|
186
|
+
----------
|
|
187
|
+
column
|
|
188
|
+
A Table column.
|
|
189
|
+
functions
|
|
190
|
+
The statistics, one result each.
|
|
191
|
+
|
|
192
|
+
Returns
|
|
193
|
+
-------
|
|
194
|
+
Column
|
|
195
|
+
One result per statistic. When the results mix kinds of values, such as a count and a text,
|
|
196
|
+
every result is written as a text.
|
|
197
|
+
|
|
198
|
+
Examples
|
|
199
|
+
--------
|
|
200
|
+
>>> import pandas
|
|
201
|
+
>>> import numdaplot as ndp
|
|
202
|
+
>>> from numdaplot.tables.description.described_frame import describe_column
|
|
203
|
+
>>> describe_column(pandas.Series(["b", "a"], dtype="string"), [ndp.Count(), ndp.Min(), ndp.Mean()]).tolist()
|
|
204
|
+
['2', 'a', <NA>]
|
|
205
|
+
"""
|
|
206
|
+
present_values = read_present_values(column)
|
|
207
|
+
value_count = len(column)
|
|
208
|
+
results = [compute_description_cell(present_values, function, value_count) for function in functions]
|
|
209
|
+
present_results = [result for result in results if result is not None]
|
|
210
|
+
result_families = {find_result_family(result) for result in present_results}
|
|
211
|
+
family_count = len(result_families)
|
|
212
|
+
time_zone = find_column_time_zone(column)
|
|
213
|
+
if family_count > SINGLE_FAMILY_COUNT:
|
|
214
|
+
results = [convert_result_to_text(result, time_zone) for result in results]
|
|
215
|
+
|
|
216
|
+
utc_column = build_result_column(results)
|
|
217
|
+
described_column = attribute_source_time_zone(utc_column, column)
|
|
218
|
+
|
|
219
|
+
return described_column
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def compute_description_cell(
|
|
223
|
+
present_values: NDArray[Any],
|
|
224
|
+
statistic: Statistic,
|
|
225
|
+
value_count: int,
|
|
226
|
+
) -> NDArray[Any] | None:
|
|
227
|
+
"""
|
|
228
|
+
Return a statistic of present values, or nothing when it does not apply or finds no value.
|
|
229
|
+
|
|
230
|
+
.. versionadded:: 0.1.0
|
|
231
|
+
|
|
232
|
+
Parameters
|
|
233
|
+
----------
|
|
234
|
+
present_values
|
|
235
|
+
One-dimensional values without missing value.
|
|
236
|
+
statistic
|
|
237
|
+
Any statistic of numdaplot.
|
|
238
|
+
value_count
|
|
239
|
+
The number of values before the missing ones were left out.
|
|
240
|
+
|
|
241
|
+
Returns
|
|
242
|
+
-------
|
|
243
|
+
NDArray or None
|
|
244
|
+
The result as a one-value array, or ``None``.
|
|
245
|
+
|
|
246
|
+
Examples
|
|
247
|
+
--------
|
|
248
|
+
>>> import numpy
|
|
249
|
+
>>> import numdaplot as ndp
|
|
250
|
+
>>> from numdaplot.tables.description.described_frame import compute_description_cell
|
|
251
|
+
>>> texts = numpy.array(["b", "a"], dtype="T")
|
|
252
|
+
>>> compute_description_cell(texts, ndp.Min(), 2)
|
|
253
|
+
array(['a'], dtype=StringDType(na_object=nan))
|
|
254
|
+
>>> print(compute_description_cell(texts, ndp.Mean(), 2))
|
|
255
|
+
None
|
|
256
|
+
"""
|
|
257
|
+
try:
|
|
258
|
+
result = compute_cell(present_values, statistic, value_count)
|
|
259
|
+
except IncompatibleTypesError:
|
|
260
|
+
return None
|
|
261
|
+
|
|
262
|
+
return result
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def find_result_family(result: NDArray[Any]) -> ValueFamily:
|
|
266
|
+
"""
|
|
267
|
+
Return the family of the type of a result.
|
|
268
|
+
|
|
269
|
+
.. versionadded:: 0.1.0
|
|
270
|
+
|
|
271
|
+
Parameters
|
|
272
|
+
----------
|
|
273
|
+
result
|
|
274
|
+
A one-value array.
|
|
275
|
+
|
|
276
|
+
Returns
|
|
277
|
+
-------
|
|
278
|
+
ValueFamily
|
|
279
|
+
The family of its type.
|
|
280
|
+
|
|
281
|
+
Examples
|
|
282
|
+
--------
|
|
283
|
+
>>> import numpy
|
|
284
|
+
>>> from numdaplot.tables.description.described_frame import find_result_family
|
|
285
|
+
>>> find_result_family(numpy.array([2]))
|
|
286
|
+
<ValueFamily.NUMBER: 1>
|
|
287
|
+
"""
|
|
288
|
+
result_type = from_numpy_dtype(result.dtype)
|
|
289
|
+
result_family = find_family(result_type)
|
|
290
|
+
|
|
291
|
+
return result_family
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def convert_result_to_text(result: NDArray[Any] | None, time_zone: TimeZone | None) -> NDArray[Any] | None:
|
|
295
|
+
"""
|
|
296
|
+
Return a result written as a text.
|
|
297
|
+
|
|
298
|
+
.. versionadded:: 0.1.0
|
|
299
|
+
|
|
300
|
+
Parameters
|
|
301
|
+
----------
|
|
302
|
+
result
|
|
303
|
+
A one-value array, or ``None``.
|
|
304
|
+
time_zone
|
|
305
|
+
The time zone of the described column: a datetime result, computed as a UTC clock time, is written
|
|
306
|
+
in this zone with its offset. ``None`` when the column has no zone.
|
|
307
|
+
|
|
308
|
+
Returns
|
|
309
|
+
-------
|
|
310
|
+
NDArray or None
|
|
311
|
+
A one-text array, or ``None`` when there is no result.
|
|
312
|
+
|
|
313
|
+
Examples
|
|
314
|
+
--------
|
|
315
|
+
>>> import numpy
|
|
316
|
+
>>> from numdaplot.tables.description.described_frame import convert_result_to_text
|
|
317
|
+
>>> convert_result_to_text(numpy.array([2]), None)
|
|
318
|
+
array(['2'], dtype=StringDType(na_object=nan))
|
|
319
|
+
"""
|
|
320
|
+
if result is None:
|
|
321
|
+
return None
|
|
322
|
+
|
|
323
|
+
python_values = to_python_list(result)
|
|
324
|
+
single_value = python_values[0]
|
|
325
|
+
shown_value = single_value
|
|
326
|
+
if time_zone is not None and isinstance(single_value, datetime):
|
|
327
|
+
utc_datetime = single_value.replace(tzinfo=UTC)
|
|
328
|
+
zone_info = ZoneInfo(time_zone.name)
|
|
329
|
+
shown_value = utc_datetime.astimezone(zone_info)
|
|
330
|
+
|
|
331
|
+
result_text = str(shown_value)
|
|
332
|
+
text_dtype = to_numpy_dtype(Type.TEXT)
|
|
333
|
+
text_result = numpy.array([result_text], dtype=text_dtype)
|
|
334
|
+
|
|
335
|
+
return text_result
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Settings of the description of the columns of a Table.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.errors.duplicate_statistic_error import DuplicateStatisticError
|
|
10
|
+
from numdaplot.errors.empty_list_error import EmptyListError
|
|
11
|
+
from numdaplot.settings.field_types import require_field_types
|
|
12
|
+
from numdaplot.statistics.count import Count
|
|
13
|
+
from numdaplot.statistics.maximum import Max
|
|
14
|
+
from numdaplot.statistics.mean import Mean
|
|
15
|
+
from numdaplot.statistics.median import Median
|
|
16
|
+
from numdaplot.statistics.minimum import Min
|
|
17
|
+
from numdaplot.statistics.quantile import Quantile
|
|
18
|
+
from numdaplot.statistics.standard_deviation import StandardDeviation
|
|
19
|
+
from numdaplot.statistics.statistic import Statistic
|
|
20
|
+
from numdaplot.tables.columns.column_names import require_column_names
|
|
21
|
+
|
|
22
|
+
LOWER_QUARTILE = 0.25
|
|
23
|
+
UPPER_QUARTILE = 0.75
|
|
24
|
+
DEFAULT_FUNCTIONS = (
|
|
25
|
+
Count(),
|
|
26
|
+
Mean(),
|
|
27
|
+
StandardDeviation(),
|
|
28
|
+
Min(),
|
|
29
|
+
Quantile(LOWER_QUARTILE),
|
|
30
|
+
Median(),
|
|
31
|
+
Quantile(UPPER_QUARTILE),
|
|
32
|
+
Max(),
|
|
33
|
+
)
|
|
34
|
+
FUNCTION_ITEM_NAME = "function"
|
|
35
|
+
COLUMN_ITEM_NAME = "column"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
class Description:
|
|
40
|
+
"""
|
|
41
|
+
Statistics describing columns of a Table, used by ``Table.describe``.
|
|
42
|
+
|
|
43
|
+
.. versionadded:: 0.1.0
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
functions
|
|
48
|
+
The ``Statistic`` objects, one row each, such as ``[ndp.Min(), ndp.Quantile(0.9)]``: see ``Statistic``
|
|
49
|
+
for every statistic. When omitted: ``Count``, ``Mean``, ``StandardDeviation``, ``Min``,
|
|
50
|
+
``Quantile(0.25)``, ``Median``, ``Quantile(0.75)`` and ``Max``, as in pandas.
|
|
51
|
+
columns
|
|
52
|
+
The names of the columns to describe, one result column each. Every number column when omitted.
|
|
53
|
+
|
|
54
|
+
Raises
|
|
55
|
+
------
|
|
56
|
+
InvalidTypeError
|
|
57
|
+
When a setting is not of the type its annotation names.
|
|
58
|
+
EmptyListError
|
|
59
|
+
When ``functions`` or ``columns`` is an empty list.
|
|
60
|
+
InvalidColumnNameError
|
|
61
|
+
When a column name is an empty text.
|
|
62
|
+
DuplicateColumnError
|
|
63
|
+
When a column name appears twice.
|
|
64
|
+
DuplicateStatisticError
|
|
65
|
+
When a statistic appears twice in ``functions``.
|
|
66
|
+
|
|
67
|
+
Examples
|
|
68
|
+
--------
|
|
69
|
+
>>> import numdaplot as ndp
|
|
70
|
+
>>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
|
|
71
|
+
>>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
|
|
72
|
+
>>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
|
|
73
|
+
>>> sales.describe(ndp.Description(functions=[ndp.Min(), ndp.Mean(), ndp.Max()]))
|
|
74
|
+
statistic price
|
|
75
|
+
TEXT FLOAT64
|
|
76
|
+
0 min 80.000000
|
|
77
|
+
1 mean 116.666667
|
|
78
|
+
2 max 150.000000
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
functions: list[Statistic] | None = None
|
|
82
|
+
columns: list[str] | None = None
|
|
83
|
+
|
|
84
|
+
def __post_init__(self) -> None:
|
|
85
|
+
"""
|
|
86
|
+
Check the lists and replace them with copies that only the description holds.
|
|
87
|
+
|
|
88
|
+
.. versionadded:: 0.1.0
|
|
89
|
+
|
|
90
|
+
Raises
|
|
91
|
+
------
|
|
92
|
+
InvalidTypeError
|
|
93
|
+
When a setting is not of the type its annotation names.
|
|
94
|
+
EmptyListError
|
|
95
|
+
When ``functions`` or ``columns`` is an empty list.
|
|
96
|
+
InvalidColumnNameError
|
|
97
|
+
When a column name is an empty text.
|
|
98
|
+
DuplicateColumnError
|
|
99
|
+
When a column name appears twice.
|
|
100
|
+
DuplicateStatisticError
|
|
101
|
+
When a statistic appears twice in ``functions``.
|
|
102
|
+
"""
|
|
103
|
+
require_field_types(self)
|
|
104
|
+
|
|
105
|
+
if self.functions == []:
|
|
106
|
+
raise EmptyListError(FUNCTION_ITEM_NAME)
|
|
107
|
+
|
|
108
|
+
if self.columns == []:
|
|
109
|
+
raise EmptyListError(COLUMN_ITEM_NAME)
|
|
110
|
+
|
|
111
|
+
if self.functions is not None:
|
|
112
|
+
require_distinct_statistics(self.functions)
|
|
113
|
+
functions_copy = list(self.functions)
|
|
114
|
+
object.__setattr__(self, "functions", functions_copy)
|
|
115
|
+
|
|
116
|
+
if self.columns is not None:
|
|
117
|
+
require_column_names(self.columns)
|
|
118
|
+
columns_copy = list(self.columns)
|
|
119
|
+
object.__setattr__(self, "columns", columns_copy)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def require_distinct_statistics(functions: list[Statistic]) -> None:
|
|
123
|
+
"""
|
|
124
|
+
Check that each statistic of a description is given once.
|
|
125
|
+
|
|
126
|
+
.. versionadded:: 0.1.0
|
|
127
|
+
|
|
128
|
+
Parameters
|
|
129
|
+
----------
|
|
130
|
+
functions
|
|
131
|
+
The statistics of the description.
|
|
132
|
+
|
|
133
|
+
Raises
|
|
134
|
+
------
|
|
135
|
+
DuplicateStatisticError
|
|
136
|
+
When a statistic appears twice, with the same settings.
|
|
137
|
+
|
|
138
|
+
Examples
|
|
139
|
+
--------
|
|
140
|
+
>>> import numdaplot as ndp
|
|
141
|
+
>>> from numdaplot.tables.description.description import require_distinct_statistics
|
|
142
|
+
>>> require_distinct_statistics([ndp.Quantile(0.25), ndp.Quantile(0.75)])
|
|
143
|
+
>>> try:
|
|
144
|
+
... require_distinct_statistics([ndp.Mean(), ndp.Mean()])
|
|
145
|
+
... except ndp.DuplicateStatisticError as error:
|
|
146
|
+
... print(error)
|
|
147
|
+
The statistic Mean() appears more than once.
|
|
148
|
+
"""
|
|
149
|
+
seen_statistics = set[Statistic]()
|
|
150
|
+
|
|
151
|
+
for function in functions:
|
|
152
|
+
if function in seen_statistics:
|
|
153
|
+
raise DuplicateStatisticError(function)
|
|
154
|
+
|
|
155
|
+
seen_statistics.add(function)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Removal of the duplicated rows of a Table.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Literal
|
|
8
|
+
|
|
9
|
+
import pandas
|
|
10
|
+
|
|
11
|
+
from numdaplot.tables.columns.column_names import require_known_columns
|
|
12
|
+
from numdaplot.tables.duplicates.deduplication import Deduplication
|
|
13
|
+
from numdaplot.tables.duplicates.keep import Keep
|
|
14
|
+
|
|
15
|
+
KEPT_ROWS = dict[Keep, Literal["first", "last", False]](
|
|
16
|
+
{
|
|
17
|
+
Keep.FIRST: "first",
|
|
18
|
+
Keep.LAST: "last",
|
|
19
|
+
Keep.NONE: False,
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def drop_duplicate_rows(frame: pandas.DataFrame, deduplication: Deduplication) -> pandas.DataFrame:
|
|
25
|
+
"""
|
|
26
|
+
Return the rows of a Table without its duplicated rows.
|
|
27
|
+
|
|
28
|
+
.. versionadded:: 0.1.0
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
frame
|
|
33
|
+
The columns of a Table.
|
|
34
|
+
deduplication
|
|
35
|
+
The compared columns and the row kept in each group of duplicates.
|
|
36
|
+
|
|
37
|
+
Returns
|
|
38
|
+
-------
|
|
39
|
+
pandas.DataFrame
|
|
40
|
+
The remaining rows, in their order, numbered from 0.
|
|
41
|
+
|
|
42
|
+
Raises
|
|
43
|
+
------
|
|
44
|
+
ColumnNotFoundError
|
|
45
|
+
When a compared column does not exist.
|
|
46
|
+
|
|
47
|
+
Examples
|
|
48
|
+
--------
|
|
49
|
+
>>> import pandas
|
|
50
|
+
>>> import numdaplot as ndp
|
|
51
|
+
>>> from numdaplot.tables.duplicates.deduplicated_frame import drop_duplicate_rows
|
|
52
|
+
>>> frame = pandas.DataFrame({"email": ["a@x.fr", "b@x.fr", "a@x.fr"], "visit": [1, 2, 3]})
|
|
53
|
+
>>> drop_duplicate_rows(frame, ndp.Deduplication(columns=["email"], keep=ndp.Keep.LAST))
|
|
54
|
+
email visit
|
|
55
|
+
0 b@x.fr 2
|
|
56
|
+
1 a@x.fr 3
|
|
57
|
+
"""
|
|
58
|
+
if deduplication.columns is not None:
|
|
59
|
+
column_names = [str(column_name) for column_name in frame.columns]
|
|
60
|
+
require_known_columns(deduplication.columns, column_names)
|
|
61
|
+
|
|
62
|
+
kept_rows = KEPT_ROWS[deduplication.keep]
|
|
63
|
+
remaining_frame = frame.drop_duplicates(subset=deduplication.columns, keep=kept_rows)
|
|
64
|
+
numbered_frame = remaining_frame.reset_index(drop=True)
|
|
65
|
+
|
|
66
|
+
return numbered_frame
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Settings of the removal of duplicated 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.columns.column_names import require_column_names
|
|
12
|
+
from numdaplot.tables.duplicates.keep import Keep
|
|
13
|
+
|
|
14
|
+
COLUMN_ITEM_NAME = "column"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class Deduplication:
|
|
19
|
+
"""
|
|
20
|
+
Which rows count as duplicates and which one is kept, used by ``Table.drop_duplicates``.
|
|
21
|
+
|
|
22
|
+
Two missing values are equal when comparing rows.
|
|
23
|
+
|
|
24
|
+
.. versionadded:: 0.1.0
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
columns
|
|
29
|
+
The names of the columns compared, every column when omitted.
|
|
30
|
+
The deduplication keeps its own copy of the list.
|
|
31
|
+
keep
|
|
32
|
+
The row kept in each group of duplicates, the first one by default.
|
|
33
|
+
|
|
34
|
+
Raises
|
|
35
|
+
------
|
|
36
|
+
InvalidTypeError
|
|
37
|
+
When a setting is not of the type its annotation names.
|
|
38
|
+
EmptyListError
|
|
39
|
+
When ``columns`` is an empty list.
|
|
40
|
+
InvalidColumnNameError
|
|
41
|
+
When a column name is an empty text.
|
|
42
|
+
DuplicateColumnError
|
|
43
|
+
When a column name appears twice.
|
|
44
|
+
|
|
45
|
+
Examples
|
|
46
|
+
--------
|
|
47
|
+
>>> import numdaplot as ndp
|
|
48
|
+
>>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
|
|
49
|
+
>>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
|
|
50
|
+
>>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
|
|
51
|
+
>>> sales.drop_duplicates(ndp.Deduplication(columns=["city"]))
|
|
52
|
+
city price
|
|
53
|
+
TEXT FLOAT64
|
|
54
|
+
0 Paris 120.0
|
|
55
|
+
1 Lyon 80.0
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
columns: list[str] | None = None
|
|
59
|
+
keep: Keep = Keep.FIRST
|
|
60
|
+
|
|
61
|
+
def __post_init__(self) -> None:
|
|
62
|
+
"""
|
|
63
|
+
Check the columns and replace them with a copy that only the deduplication 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 ``columns`` is an empty list.
|
|
73
|
+
InvalidColumnNameError
|
|
74
|
+
When a column name is an empty text.
|
|
75
|
+
DuplicateColumnError
|
|
76
|
+
When a column name appears twice.
|
|
77
|
+
"""
|
|
78
|
+
require_field_types(self)
|
|
79
|
+
|
|
80
|
+
if self.columns is None:
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if self.columns == []:
|
|
84
|
+
raise EmptyListError(COLUMN_ITEM_NAME)
|
|
85
|
+
|
|
86
|
+
require_column_names(self.columns)
|
|
87
|
+
columns_copy = list(self.columns)
|
|
88
|
+
object.__setattr__(self, "columns", columns_copy)
|