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,117 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Refusal of the dates and durations pandas cannot store in a Table column.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from types import TracebackType
|
|
8
|
+
|
|
9
|
+
import pandas
|
|
10
|
+
|
|
11
|
+
from numdaplot.data_types.type import Type
|
|
12
|
+
from numdaplot.errors.time_overflow_error import TimeOverflowError
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TimeRangeErrors:
|
|
16
|
+
"""
|
|
17
|
+
Context giving the out of range errors of pandas in a block as ``TimeOverflowError``, naming the column.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
operation_name
|
|
24
|
+
The operation shown in the message.
|
|
25
|
+
column_name
|
|
26
|
+
The name of the column the block works on.
|
|
27
|
+
|
|
28
|
+
Examples
|
|
29
|
+
--------
|
|
30
|
+
>>> import numpy
|
|
31
|
+
>>> import pandas
|
|
32
|
+
>>> import numdaplot as ndp
|
|
33
|
+
>>> from numdaplot.tables.frames.time_range_errors import TimeRangeErrors
|
|
34
|
+
>>> far_moments = pandas.Series(numpy.array(["3000-01-01"], dtype="datetime64[s]"))
|
|
35
|
+
>>> try:
|
|
36
|
+
... with TimeRangeErrors("from_arrays", "day"):
|
|
37
|
+
... far_moments.astype("datetime64[ns]")
|
|
38
|
+
... except ndp.TimeOverflowError as error:
|
|
39
|
+
... print(error)
|
|
40
|
+
The operation from_arrays gives values of the column 'day' outside the range of DATETIME, from 1677 to 2262.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(self, operation_name: str, column_name: str) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Keep the operation and the column of the block.
|
|
46
|
+
|
|
47
|
+
.. versionadded:: 0.1.0
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
operation_name
|
|
52
|
+
The operation shown in the message.
|
|
53
|
+
column_name
|
|
54
|
+
The name of the column the block works on.
|
|
55
|
+
"""
|
|
56
|
+
self.operation_name = operation_name
|
|
57
|
+
self.column_name = column_name
|
|
58
|
+
|
|
59
|
+
def __enter__(self) -> None:
|
|
60
|
+
"""
|
|
61
|
+
Start the block.
|
|
62
|
+
|
|
63
|
+
.. versionadded:: 0.1.0
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __exit__(
|
|
67
|
+
self,
|
|
68
|
+
error_type: type[BaseException] | None,
|
|
69
|
+
error: BaseException | None,
|
|
70
|
+
traceback: TracebackType | None,
|
|
71
|
+
) -> None:
|
|
72
|
+
"""
|
|
73
|
+
Replace an out of range error of pandas raised by the block.
|
|
74
|
+
|
|
75
|
+
.. versionadded:: 0.1.0
|
|
76
|
+
|
|
77
|
+
Parameters
|
|
78
|
+
----------
|
|
79
|
+
error_type
|
|
80
|
+
The type of the error raised by the block, or None.
|
|
81
|
+
error
|
|
82
|
+
The error raised by the block, or None.
|
|
83
|
+
traceback
|
|
84
|
+
Its traceback, or None.
|
|
85
|
+
|
|
86
|
+
Raises
|
|
87
|
+
------
|
|
88
|
+
TimeOverflowError
|
|
89
|
+
When the block raised ``OutOfBoundsDatetime`` or ``OutOfBoundsTimedelta``.
|
|
90
|
+
"""
|
|
91
|
+
if isinstance(error, pandas.errors.OutOfBoundsDatetime):
|
|
92
|
+
self.raise_overflow(Type.DATETIME, error)
|
|
93
|
+
|
|
94
|
+
if isinstance(error, pandas.errors.OutOfBoundsTimedelta):
|
|
95
|
+
self.raise_overflow(Type.DURATION, error)
|
|
96
|
+
|
|
97
|
+
def raise_overflow(self, data_type: Type, error: BaseException) -> None:
|
|
98
|
+
"""
|
|
99
|
+
Raise the error of a value out of the range of a type.
|
|
100
|
+
|
|
101
|
+
.. versionadded:: 0.1.0
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
data_type
|
|
106
|
+
The type that cannot hold the value.
|
|
107
|
+
error
|
|
108
|
+
The error of pandas.
|
|
109
|
+
|
|
110
|
+
Raises
|
|
111
|
+
------
|
|
112
|
+
TimeOverflowError
|
|
113
|
+
Always.
|
|
114
|
+
"""
|
|
115
|
+
overflow_error = TimeOverflowError(self.operation_name, data_type.name)
|
|
116
|
+
overflow_error.name_column(self.column_name)
|
|
117
|
+
raise overflow_error from error
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Time zones of the datetime columns of a Table.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import cast
|
|
8
|
+
|
|
9
|
+
import pandas
|
|
10
|
+
|
|
11
|
+
from numdaplot.data_types.library import Library
|
|
12
|
+
from numdaplot.data_types.type import Type
|
|
13
|
+
from numdaplot.dates.time_zone import TimeZone
|
|
14
|
+
from numdaplot.errors.time_zone_mismatch_error import TimeZoneMismatchError
|
|
15
|
+
from numdaplot.errors.unknown_time_zone_error import UnknownTimeZoneError
|
|
16
|
+
from numdaplot.errors.unsupported_type_error import UnsupportedTypeError
|
|
17
|
+
from numdaplot.tables.frames.column import Column
|
|
18
|
+
|
|
19
|
+
UTC_ZONE_NAME = "UTC"
|
|
20
|
+
NANOSECOND_UNIT = "ns"
|
|
21
|
+
TYPE_AND_ZONE = "{type_name} {zone_name}"
|
|
22
|
+
DATETIME_KIND = "M"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def find_column_time_zone(column: Column) -> TimeZone | None:
|
|
26
|
+
"""
|
|
27
|
+
Return the time zone of a Table column.
|
|
28
|
+
|
|
29
|
+
.. versionadded:: 0.1.0
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
column
|
|
34
|
+
A Table column.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
TimeZone or None
|
|
39
|
+
The zone of a datetime column with a time zone, ``None`` for any other column.
|
|
40
|
+
|
|
41
|
+
Examples
|
|
42
|
+
--------
|
|
43
|
+
>>> import pandas
|
|
44
|
+
>>> from numdaplot.tables.frames.time_zones import find_column_time_zone
|
|
45
|
+
>>> find_column_time_zone(pandas.Series(pandas.to_datetime(["2026-07-01 10:30"])).dt.tz_localize("Europe/Paris"))
|
|
46
|
+
TimeZone(name='Europe/Paris')
|
|
47
|
+
"""
|
|
48
|
+
column_dtype = column.dtype
|
|
49
|
+
if not isinstance(column_dtype, pandas.DatetimeTZDtype):
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
zone_name = str(column_dtype.tz)
|
|
53
|
+
time_zone = TimeZone(zone_name)
|
|
54
|
+
|
|
55
|
+
return time_zone
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def name_column_type(column: Column, column_type: Type) -> str:
|
|
59
|
+
"""
|
|
60
|
+
Return the type shown under the name of a Table column, followed by its time zone when it has one.
|
|
61
|
+
|
|
62
|
+
.. versionadded:: 0.1.0
|
|
63
|
+
|
|
64
|
+
Parameters
|
|
65
|
+
----------
|
|
66
|
+
column
|
|
67
|
+
A Table column.
|
|
68
|
+
column_type
|
|
69
|
+
The numdaplot type of the column.
|
|
70
|
+
|
|
71
|
+
Returns
|
|
72
|
+
-------
|
|
73
|
+
str
|
|
74
|
+
The name of the type, such as ``"FLOAT64"`` or ``"DATETIME Europe/Paris"``.
|
|
75
|
+
|
|
76
|
+
Examples
|
|
77
|
+
--------
|
|
78
|
+
>>> import pandas
|
|
79
|
+
>>> import numdaplot as ndp
|
|
80
|
+
>>> from numdaplot.tables.frames.time_zones import name_column_type
|
|
81
|
+
>>> name_column_type(pandas.Series([1.5]), ndp.Type.FLOAT64)
|
|
82
|
+
'FLOAT64'
|
|
83
|
+
"""
|
|
84
|
+
time_zone = find_column_time_zone(column)
|
|
85
|
+
if time_zone is None:
|
|
86
|
+
return column_type.name
|
|
87
|
+
|
|
88
|
+
type_and_zone = TYPE_AND_ZONE.format(type_name=column_type.name, zone_name=time_zone.name)
|
|
89
|
+
|
|
90
|
+
return type_and_zone
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def normalize_time_zone_column(column: Column) -> Column:
|
|
94
|
+
"""
|
|
95
|
+
Return a datetime column with a time zone, counted in nanoseconds, its zone named by its IANA name.
|
|
96
|
+
|
|
97
|
+
.. versionadded:: 0.1.0
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
column
|
|
102
|
+
A pandas column of datetimes with a time zone.
|
|
103
|
+
|
|
104
|
+
Returns
|
|
105
|
+
-------
|
|
106
|
+
pandas.Series
|
|
107
|
+
The same instants in the same zone.
|
|
108
|
+
|
|
109
|
+
Raises
|
|
110
|
+
------
|
|
111
|
+
UnsupportedTypeError
|
|
112
|
+
When the zone is not an IANA time zone, such as a fixed offset of one hour.
|
|
113
|
+
|
|
114
|
+
Examples
|
|
115
|
+
--------
|
|
116
|
+
>>> import pandas
|
|
117
|
+
>>> from numdaplot.tables.frames.time_zones import normalize_time_zone_column
|
|
118
|
+
>>> times = pandas.Series(pandas.to_datetime(["2026-07-01 10:30"])).dt.tz_localize("UTC").dt.as_unit("s")
|
|
119
|
+
>>> str(normalize_time_zone_column(times).dtype)
|
|
120
|
+
'datetime64[ns, UTC]'
|
|
121
|
+
"""
|
|
122
|
+
column_dtype = cast(pandas.DatetimeTZDtype, column.dtype)
|
|
123
|
+
zone_name = str(column_dtype.tz)
|
|
124
|
+
try:
|
|
125
|
+
TimeZone(zone_name)
|
|
126
|
+
except UnknownTimeZoneError as error:
|
|
127
|
+
dtype_name = str(column_dtype)
|
|
128
|
+
raise UnsupportedTypeError(dtype_name, Library.PANDAS) from error
|
|
129
|
+
|
|
130
|
+
nanosecond_column = column.dt.as_unit(NANOSECOND_UNIT)
|
|
131
|
+
named_column = nanosecond_column.dt.tz_convert(zone_name)
|
|
132
|
+
|
|
133
|
+
return named_column
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def remove_utc_zone(column: Column) -> Column:
|
|
137
|
+
"""
|
|
138
|
+
Return the instants of a datetime column with a time zone as datetimes without zone, in UTC.
|
|
139
|
+
|
|
140
|
+
.. versionadded:: 0.1.0
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
column
|
|
145
|
+
A Table column of datetimes with a time zone.
|
|
146
|
+
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
pandas.Series
|
|
150
|
+
The UTC clock time of each instant, without time zone.
|
|
151
|
+
|
|
152
|
+
Examples
|
|
153
|
+
--------
|
|
154
|
+
>>> import pandas
|
|
155
|
+
>>> from numdaplot.tables.frames.time_zones import remove_utc_zone
|
|
156
|
+
>>> times = pandas.Series(pandas.to_datetime(["2026-07-01 10:30"])).dt.tz_localize("Europe/Paris")
|
|
157
|
+
>>> remove_utc_zone(times).tolist()
|
|
158
|
+
[Timestamp('2026-07-01 08:30:00')]
|
|
159
|
+
"""
|
|
160
|
+
utc_column = column.dt.tz_convert(UTC_ZONE_NAME)
|
|
161
|
+
naive_column = utc_column.dt.tz_localize(None)
|
|
162
|
+
|
|
163
|
+
return naive_column
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def attribute_utc_results(column: Column, time_zone: TimeZone) -> Column:
|
|
167
|
+
"""
|
|
168
|
+
Return datetimes computed in UTC without zone as the same instants in a time zone.
|
|
169
|
+
|
|
170
|
+
.. versionadded:: 0.1.0
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
column
|
|
175
|
+
A Table column of datetimes without time zone, holding UTC clock times.
|
|
176
|
+
time_zone
|
|
177
|
+
The zone to show the instants in.
|
|
178
|
+
|
|
179
|
+
Returns
|
|
180
|
+
-------
|
|
181
|
+
pandas.Series
|
|
182
|
+
The instants in the zone.
|
|
183
|
+
|
|
184
|
+
Examples
|
|
185
|
+
--------
|
|
186
|
+
>>> import pandas
|
|
187
|
+
>>> import numdaplot as ndp
|
|
188
|
+
>>> from numdaplot.tables.frames.time_zones import attribute_utc_results
|
|
189
|
+
>>> times = pandas.Series(pandas.to_datetime(["2026-07-01 08:30"]))
|
|
190
|
+
>>> attribute_utc_results(times, ndp.TimeZone("Europe/Paris")).tolist()
|
|
191
|
+
[Timestamp('2026-07-01 10:30:00+0200', tz='Europe/Paris')]
|
|
192
|
+
"""
|
|
193
|
+
utc_column = column.dt.tz_localize(UTC_ZONE_NAME)
|
|
194
|
+
zone_column = utc_column.dt.tz_convert(time_zone.name)
|
|
195
|
+
|
|
196
|
+
return zone_column
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def attribute_source_time_zone(results: Column, source: Column) -> Column:
|
|
200
|
+
"""
|
|
201
|
+
Return statistics of a column in the time zone of that column, when they are datetimes and it has one.
|
|
202
|
+
|
|
203
|
+
.. versionadded:: 0.1.0
|
|
204
|
+
|
|
205
|
+
Parameters
|
|
206
|
+
----------
|
|
207
|
+
results
|
|
208
|
+
Statistics computed on the UTC clock times of ``source``.
|
|
209
|
+
source
|
|
210
|
+
The column the statistics are computed on.
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
pandas.Series
|
|
215
|
+
The datetime results in the zone of the source column, or the results themselves otherwise.
|
|
216
|
+
|
|
217
|
+
Examples
|
|
218
|
+
--------
|
|
219
|
+
>>> import pandas
|
|
220
|
+
>>> from numdaplot.tables.frames.time_zones import attribute_source_time_zone
|
|
221
|
+
>>> source = pandas.Series(pandas.to_datetime(["2026-07-01 10:30"])).dt.tz_localize("Europe/Paris")
|
|
222
|
+
>>> attribute_source_time_zone(pandas.Series(pandas.to_datetime(["2026-07-01 08:30"])), source).tolist()
|
|
223
|
+
[Timestamp('2026-07-01 10:30:00+0200', tz='Europe/Paris')]
|
|
224
|
+
"""
|
|
225
|
+
time_zone = find_column_time_zone(source)
|
|
226
|
+
if time_zone is None:
|
|
227
|
+
return results
|
|
228
|
+
|
|
229
|
+
is_datetime_result = results.dtype.kind == DATETIME_KIND
|
|
230
|
+
if not is_datetime_result:
|
|
231
|
+
return results
|
|
232
|
+
|
|
233
|
+
zone_results = attribute_utc_results(results, time_zone)
|
|
234
|
+
|
|
235
|
+
return zone_results
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def require_no_time_zone(frame: pandas.DataFrame, operation: str) -> None:
|
|
239
|
+
"""
|
|
240
|
+
Check that no column of a Table holds datetimes with a time zone.
|
|
241
|
+
|
|
242
|
+
.. versionadded:: 0.1.0
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
frame
|
|
247
|
+
The columns of a Table.
|
|
248
|
+
operation
|
|
249
|
+
What needs datetimes without zone, shown in the error message, such as ``"An Excel file"``.
|
|
250
|
+
|
|
251
|
+
Raises
|
|
252
|
+
------
|
|
253
|
+
TimeZoneMismatchError
|
|
254
|
+
When a column holds datetimes with a time zone.
|
|
255
|
+
|
|
256
|
+
Examples
|
|
257
|
+
--------
|
|
258
|
+
>>> import pandas
|
|
259
|
+
>>> import numdaplot as ndp
|
|
260
|
+
>>> from numdaplot.tables.frames.time_zones import require_no_time_zone
|
|
261
|
+
>>> times = pandas.Series(pandas.to_datetime(["2026-07-01 10:30"])).dt.tz_localize("UTC")
|
|
262
|
+
>>> try:
|
|
263
|
+
... require_no_time_zone(pandas.DataFrame({"time": times}), "An Excel file")
|
|
264
|
+
... except ndp.TimeZoneMismatchError as error:
|
|
265
|
+
... print(error)
|
|
266
|
+
An Excel file needs datetimes without a time zone.
|
|
267
|
+
"""
|
|
268
|
+
for _, column in frame.items():
|
|
269
|
+
time_zone = find_column_time_zone(column)
|
|
270
|
+
if time_zone is not None:
|
|
271
|
+
raise TimeZoneMismatchError(operation, False)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Settings of a join of two Tables.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from numdaplot.errors.empty_list_error import EmptyListError
|
|
13
|
+
from numdaplot.settings.field_types import require_field_types
|
|
14
|
+
from numdaplot.tables.columns.column_names import require_column_names
|
|
15
|
+
from numdaplot.tables.joining.join_mode import JoinMode
|
|
16
|
+
from numdaplot.tables.joining.join_suffixes import JoinSuffixes
|
|
17
|
+
from numdaplot.tables.joining.key_types import KeyTypes
|
|
18
|
+
from numdaplot.tables.joining.relation import Relation
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from numdaplot.tables.table import Table
|
|
22
|
+
|
|
23
|
+
KEY_ITEM_NAME = "key"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# eq=False because comparing two settings would compare their Tables with ==, which they refuse.
|
|
27
|
+
@dataclass(frozen=True, eq=False)
|
|
28
|
+
class Join:
|
|
29
|
+
"""
|
|
30
|
+
Settings of a join of two Tables on the values of key columns, used by ``Table.join``.
|
|
31
|
+
|
|
32
|
+
Each row of the joined Table meets each row of the other Table having the same keys. A missing key never matches,
|
|
33
|
+
as in SQL. The rows of the joined Table come first, in their order, then the unmatched rows of the other Table.
|
|
34
|
+
The columns are the keys, then the other columns of the joined Table, then those of the other Table.
|
|
35
|
+
|
|
36
|
+
.. versionadded:: 0.1.0
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
other
|
|
41
|
+
The Table joined to this one.
|
|
42
|
+
keys
|
|
43
|
+
The names of the key columns, which both Tables have: rename them with ``Table.rename`` first when they differ.
|
|
44
|
+
Several keys match on their combination. The join keeps its own copy of the list.
|
|
45
|
+
mode
|
|
46
|
+
Which rows are kept, ``JoinMode.INNER`` by default: only the rows whose keys match.
|
|
47
|
+
suffixes
|
|
48
|
+
The suffixes of the columns both Tables have besides the keys. When omitted, such a column raises
|
|
49
|
+
``DuplicateColumnError``.
|
|
50
|
+
key_types
|
|
51
|
+
How close the types of each key must be, ``KeyTypes.SAME_FAMILY`` by default: ``INT64`` matches ``FLOAT64``.
|
|
52
|
+
relation
|
|
53
|
+
How many times each key may appear in this Table, the left one, and in the other Table, the right one,
|
|
54
|
+
``Relation.MANY_TO_MANY`` by default, which checks nothing.
|
|
55
|
+
|
|
56
|
+
Raises
|
|
57
|
+
------
|
|
58
|
+
InvalidTypeError
|
|
59
|
+
When a setting is not of the type its annotation names.
|
|
60
|
+
EmptyListError
|
|
61
|
+
When ``keys`` is an empty list.
|
|
62
|
+
InvalidColumnNameError
|
|
63
|
+
When a name in ``keys`` is an empty text.
|
|
64
|
+
DuplicateColumnError
|
|
65
|
+
When a name appears twice in ``keys``.
|
|
66
|
+
|
|
67
|
+
Examples
|
|
68
|
+
--------
|
|
69
|
+
>>> import numdaplot as ndp
|
|
70
|
+
>>> accidents = ndp.Table.from_arrays({"id": ndp.Array.from_list([1, 2]), "dep": ndp.Array.from_list(["75", "69"])})
|
|
71
|
+
>>> users = ndp.Table.from_arrays({"id": ndp.Array.from_list([1, 1]), "age": ndp.Array.from_list([34, 8])})
|
|
72
|
+
>>> accidents.join(ndp.Join(other=users, keys=["id"]))
|
|
73
|
+
id dep age
|
|
74
|
+
INT64 TEXT INT64
|
|
75
|
+
0 1 75 34
|
|
76
|
+
1 1 75 8
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
other: Table
|
|
80
|
+
keys: list[str]
|
|
81
|
+
mode: JoinMode = JoinMode.INNER
|
|
82
|
+
suffixes: JoinSuffixes | None = None
|
|
83
|
+
key_types: KeyTypes = KeyTypes.SAME_FAMILY
|
|
84
|
+
relation: Relation = Relation.MANY_TO_MANY
|
|
85
|
+
|
|
86
|
+
def __post_init__(self) -> None:
|
|
87
|
+
"""
|
|
88
|
+
Check the keys and replace them with a copy that only the join holds.
|
|
89
|
+
|
|
90
|
+
.. versionadded:: 0.1.0
|
|
91
|
+
|
|
92
|
+
Raises
|
|
93
|
+
------
|
|
94
|
+
InvalidTypeError
|
|
95
|
+
When a setting is not of the type its annotation names.
|
|
96
|
+
EmptyListError
|
|
97
|
+
When ``keys`` is an empty list.
|
|
98
|
+
InvalidColumnNameError
|
|
99
|
+
When a name in ``keys`` is an empty text.
|
|
100
|
+
DuplicateColumnError
|
|
101
|
+
When a name appears twice in ``keys``.
|
|
102
|
+
"""
|
|
103
|
+
require_field_types(self)
|
|
104
|
+
|
|
105
|
+
if self.keys == []:
|
|
106
|
+
raise EmptyListError(KEY_ITEM_NAME)
|
|
107
|
+
|
|
108
|
+
require_column_names(self.keys)
|
|
109
|
+
keys_copy = list(self.keys)
|
|
110
|
+
object.__setattr__(self, "keys", keys_copy)
|