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,166 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Columns of the result of a join of two Tables.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import numpy
|
|
8
|
+
import pandas
|
|
9
|
+
from numpy.typing import NDArray
|
|
10
|
+
|
|
11
|
+
from numdaplot.tables.joining.join import Join
|
|
12
|
+
from numdaplot.tables.joining.join_keys import align_key_frames
|
|
13
|
+
from numdaplot.tables.joining.join_relation import require_relation
|
|
14
|
+
from numdaplot.tables.joining.joined_names import name_joined_columns
|
|
15
|
+
from numdaplot.tables.joining.joined_rows import pair_rows
|
|
16
|
+
from numdaplot.tables.table_data import read_stored_frame
|
|
17
|
+
|
|
18
|
+
COLUMN_AXIS = 1
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def join_frames(frame: pandas.DataFrame, join: Join) -> pandas.DataFrame:
|
|
22
|
+
"""
|
|
23
|
+
Return the columns of the join of the columns of a Table with the other Table of a join.
|
|
24
|
+
|
|
25
|
+
.. versionadded:: 0.1.0
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
frame
|
|
30
|
+
The columns of the joined Table.
|
|
31
|
+
join
|
|
32
|
+
The other Table, the keys and the settings of the join.
|
|
33
|
+
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
pandas.DataFrame
|
|
37
|
+
The keys, then the other columns of the joined Table, then those of the other Table, one row per pair of
|
|
38
|
+
rows, missing values where a Table has no row.
|
|
39
|
+
|
|
40
|
+
Raises
|
|
41
|
+
------
|
|
42
|
+
ColumnNotFoundError
|
|
43
|
+
When a key is missing from one of the Tables.
|
|
44
|
+
IncompatibleTypesError
|
|
45
|
+
When the two columns of a key cannot match.
|
|
46
|
+
TimeZoneMismatchError
|
|
47
|
+
When the two columns of a key hold datetimes of different time zones, or with and without one.
|
|
48
|
+
JoinRelationError
|
|
49
|
+
When a key is repeated in a Table where the relation of the join expects it once.
|
|
50
|
+
DuplicateColumnError
|
|
51
|
+
When both Tables have a column besides the keys and no suffixes are given, or a suffixed name is already
|
|
52
|
+
taken.
|
|
53
|
+
|
|
54
|
+
Examples
|
|
55
|
+
--------
|
|
56
|
+
>>> import pandas
|
|
57
|
+
>>> import numdaplot as ndp
|
|
58
|
+
>>> from numdaplot.tables.joining.joined_frame import join_frames
|
|
59
|
+
>>> users = ndp.Table.from_arrays({"id": ndp.Array.from_list([1, 3]), "age": ndp.Array.from_list([34, 51])})
|
|
60
|
+
>>> frame = pandas.DataFrame({"id": pandas.array([1, 2], dtype="Int64")})
|
|
61
|
+
>>> join_frames(frame, ndp.Join(other=users, keys=["id"], mode=ndp.JoinMode.LEFT))["age"].tolist()
|
|
62
|
+
[34, <NA>]
|
|
63
|
+
"""
|
|
64
|
+
other_frame = read_stored_frame(join.other)
|
|
65
|
+
key_frame, other_key_frame = align_key_frames(frame, other_frame, join.keys, join.key_types)
|
|
66
|
+
require_relation(key_frame, other_key_frame, join.relation)
|
|
67
|
+
column_names = frame.columns.tolist()
|
|
68
|
+
other_names = other_frame.columns.tolist()
|
|
69
|
+
joined_names, other_joined_names = name_joined_columns(column_names, other_names, join.keys, join.suffixes)
|
|
70
|
+
rows, other_rows = pair_rows(key_frame, other_key_frame, join.mode)
|
|
71
|
+
joined_keys = join_key_columns(key_frame, other_key_frame, rows, other_rows)
|
|
72
|
+
kept_frame = frame.drop(columns=join.keys)
|
|
73
|
+
other_kept_frame = other_frame.drop(columns=join.keys)
|
|
74
|
+
joined_frame = take_rows(kept_frame, rows)
|
|
75
|
+
other_joined_frame = take_rows(other_kept_frame, other_rows)
|
|
76
|
+
joined_frame.columns = pandas.Index(joined_names)
|
|
77
|
+
other_joined_frame.columns = pandas.Index(other_joined_names)
|
|
78
|
+
result_frame = pandas.concat([joined_keys, joined_frame, other_joined_frame], axis=COLUMN_AXIS)
|
|
79
|
+
|
|
80
|
+
return result_frame
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def join_key_columns(
|
|
84
|
+
key_frame: pandas.DataFrame,
|
|
85
|
+
other_key_frame: pandas.DataFrame,
|
|
86
|
+
rows: NDArray[numpy.intp],
|
|
87
|
+
other_rows: NDArray[numpy.intp],
|
|
88
|
+
) -> pandas.DataFrame:
|
|
89
|
+
"""
|
|
90
|
+
Return one column per key: the key of the joined Table, or of the other Table where the joined one has no row.
|
|
91
|
+
|
|
92
|
+
.. versionadded:: 0.1.0
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
key_frame
|
|
97
|
+
The key columns of the joined Table.
|
|
98
|
+
other_key_frame
|
|
99
|
+
The key columns of the other Table, of the same names and types.
|
|
100
|
+
rows
|
|
101
|
+
The row of the joined Table of each row of the result, -1 where it has none.
|
|
102
|
+
other_rows
|
|
103
|
+
The row of the other Table of each row of the result, -1 where it has none.
|
|
104
|
+
|
|
105
|
+
Returns
|
|
106
|
+
-------
|
|
107
|
+
pandas.DataFrame
|
|
108
|
+
The keys of each row of the result, numbered from 0.
|
|
109
|
+
|
|
110
|
+
Examples
|
|
111
|
+
--------
|
|
112
|
+
>>> import numpy
|
|
113
|
+
>>> import pandas
|
|
114
|
+
>>> from numdaplot.tables.joining.joined_frame import join_key_columns
|
|
115
|
+
>>> key_frame = pandas.DataFrame({"id": [1.0, 2.0]})
|
|
116
|
+
>>> other_key_frame = pandas.DataFrame({"id": [3.0, 1.0]})
|
|
117
|
+
>>> join_key_columns(key_frame, other_key_frame, numpy.array([0, 1, -1]), numpy.array([1, -1, 0]))["id"].tolist()
|
|
118
|
+
[1.0, 2.0, 3.0]
|
|
119
|
+
"""
|
|
120
|
+
joined_keys = take_rows(key_frame, rows)
|
|
121
|
+
other_joined_keys = take_rows(other_key_frame, other_rows)
|
|
122
|
+
has_row = rows >= 0
|
|
123
|
+
key_columns = dict[str, pandas.Series]()
|
|
124
|
+
|
|
125
|
+
for key_name in key_frame.columns:
|
|
126
|
+
key_column = joined_keys[key_name]
|
|
127
|
+
other_key_column = other_joined_keys[key_name]
|
|
128
|
+
combined_column = key_column.where(has_row, other_key_column)
|
|
129
|
+
key_columns[key_name] = combined_column
|
|
130
|
+
|
|
131
|
+
key_columns_frame = pandas.DataFrame(key_columns)
|
|
132
|
+
|
|
133
|
+
return key_columns_frame
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def take_rows(frame: pandas.DataFrame, rows: NDArray[numpy.intp]) -> pandas.DataFrame:
|
|
137
|
+
"""
|
|
138
|
+
Return the given rows of the columns of a Table, a row of missing values for each -1.
|
|
139
|
+
|
|
140
|
+
.. versionadded:: 0.1.0
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
frame
|
|
145
|
+
The columns of a Table, rows numbered from 0.
|
|
146
|
+
rows
|
|
147
|
+
The row numbers taken, in order, possibly repeated, -1 for a row of missing values.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
pandas.DataFrame
|
|
152
|
+
The rows taken, numbered from 0, each column keeping its type.
|
|
153
|
+
|
|
154
|
+
Examples
|
|
155
|
+
--------
|
|
156
|
+
>>> import numpy
|
|
157
|
+
>>> import pandas
|
|
158
|
+
>>> from numdaplot.tables.joining.joined_frame import take_rows
|
|
159
|
+
>>> ages = pandas.DataFrame({"age": pandas.array([34, 51], dtype="Int64")})
|
|
160
|
+
>>> take_rows(ages, numpy.array([1, -1]))["age"].tolist()
|
|
161
|
+
[51, <NA>]
|
|
162
|
+
"""
|
|
163
|
+
taken_frame = frame.reindex(rows)
|
|
164
|
+
numbered_frame = taken_frame.reset_index(drop=True)
|
|
165
|
+
|
|
166
|
+
return numbered_frame
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Names of the columns of a join that are not keys.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from numdaplot.errors.duplicate_column_error import DuplicateColumnError
|
|
8
|
+
from numdaplot.tables.columns.column_names import require_unique_names
|
|
9
|
+
from numdaplot.tables.joining.join_suffixes import JoinSuffixes
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def name_joined_columns(
|
|
13
|
+
column_names: list[str], other_names: list[str], keys: list[str], suffixes: JoinSuffixes | None
|
|
14
|
+
) -> tuple[list[str], list[str]]:
|
|
15
|
+
"""
|
|
16
|
+
Return the names the columns of both Tables take in a join, besides the keys.
|
|
17
|
+
|
|
18
|
+
.. versionadded:: 0.1.0
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
column_names
|
|
23
|
+
The column names of the joined Table.
|
|
24
|
+
other_names
|
|
25
|
+
The column names of the other Table.
|
|
26
|
+
keys
|
|
27
|
+
The names of the key columns, left out of both lists.
|
|
28
|
+
suffixes
|
|
29
|
+
The suffixes of the columns both Tables have, or None.
|
|
30
|
+
|
|
31
|
+
Returns
|
|
32
|
+
-------
|
|
33
|
+
tuple[list[str], list[str]]
|
|
34
|
+
The names of the other columns of the joined Table, then of the other Table, in their order, a suffix added
|
|
35
|
+
to each name both have.
|
|
36
|
+
|
|
37
|
+
Raises
|
|
38
|
+
------
|
|
39
|
+
DuplicateColumnError
|
|
40
|
+
When both Tables have a column besides the keys and no suffixes are given, or a suffixed name is already the
|
|
41
|
+
name of another column.
|
|
42
|
+
|
|
43
|
+
Examples
|
|
44
|
+
--------
|
|
45
|
+
>>> import numdaplot as ndp
|
|
46
|
+
>>> from numdaplot.tables.joining.joined_names import name_joined_columns
|
|
47
|
+
>>> years = ndp.JoinSuffixes(left="_2024", right="_2025")
|
|
48
|
+
>>> name_joined_columns(["dep", "deaths", "area"], ["dep", "deaths"], ["dep"], years)
|
|
49
|
+
(['deaths_2024', 'area'], ['deaths_2025'])
|
|
50
|
+
"""
|
|
51
|
+
key_names = set(keys)
|
|
52
|
+
kept_names = [column_name for column_name in column_names if column_name not in key_names]
|
|
53
|
+
other_kept_names = [other_name for other_name in other_names if other_name not in key_names]
|
|
54
|
+
shared_names = set(kept_names) & set(other_kept_names)
|
|
55
|
+
shared_name_list = [column_name for column_name in kept_names if column_name in shared_names]
|
|
56
|
+
needs_suffixes = suffixes is None and shared_name_list != []
|
|
57
|
+
if needs_suffixes:
|
|
58
|
+
raise DuplicateColumnError(shared_name_list[0])
|
|
59
|
+
|
|
60
|
+
joined_names = kept_names
|
|
61
|
+
other_joined_names = other_kept_names
|
|
62
|
+
if suffixes is not None:
|
|
63
|
+
joined_names = add_suffix(kept_names, shared_names, suffixes.left)
|
|
64
|
+
other_joined_names = add_suffix(other_kept_names, shared_names, suffixes.right)
|
|
65
|
+
|
|
66
|
+
all_names = [*keys, *joined_names, *other_joined_names]
|
|
67
|
+
require_unique_names(all_names)
|
|
68
|
+
|
|
69
|
+
return joined_names, other_joined_names
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def add_suffix(column_names: list[str], shared_names: set[str], suffix: str) -> list[str]:
|
|
73
|
+
"""
|
|
74
|
+
Return the column names with a suffix added to each name both Tables of a join have.
|
|
75
|
+
|
|
76
|
+
.. versionadded:: 0.1.0
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
column_names
|
|
81
|
+
The column names of one Table, besides the keys.
|
|
82
|
+
shared_names
|
|
83
|
+
The names both Tables have, besides the keys.
|
|
84
|
+
suffix
|
|
85
|
+
The suffix of this Table.
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
list[str]
|
|
90
|
+
The names in their order, the shared ones followed by the suffix.
|
|
91
|
+
|
|
92
|
+
Examples
|
|
93
|
+
--------
|
|
94
|
+
>>> from numdaplot.tables.joining.joined_names import add_suffix
|
|
95
|
+
>>> add_suffix(["deaths", "area"], {"deaths"}, "_2024")
|
|
96
|
+
['deaths_2024', 'area']
|
|
97
|
+
"""
|
|
98
|
+
suffixed_names = list[str]()
|
|
99
|
+
|
|
100
|
+
for column_name in column_names:
|
|
101
|
+
suffixed_name = column_name
|
|
102
|
+
if column_name in shared_names:
|
|
103
|
+
suffixed_name = column_name + suffix
|
|
104
|
+
|
|
105
|
+
suffixed_names.append(suffixed_name)
|
|
106
|
+
|
|
107
|
+
return suffixed_names
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The rows of two Tables that a join puts side by side.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import numpy
|
|
8
|
+
import pandas
|
|
9
|
+
from numpy.typing import NDArray
|
|
10
|
+
|
|
11
|
+
from numdaplot.tables.joining.join_mode import JoinMode
|
|
12
|
+
|
|
13
|
+
NO_ROW = -1
|
|
14
|
+
ROW_DTYPE = numpy.dtype(numpy.intp)
|
|
15
|
+
ROWS_AXIS = 1
|
|
16
|
+
KEEPS_UNMATCHED_ROWS = frozenset({JoinMode.LEFT, JoinMode.OUTER})
|
|
17
|
+
KEEPS_UNMATCHED_OTHER_ROWS = frozenset({JoinMode.RIGHT, JoinMode.OUTER})
|
|
18
|
+
INNER_MERGE = "inner"
|
|
19
|
+
STABLE_SORT = "stable"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def pair_rows(
|
|
23
|
+
key_frame: pandas.DataFrame, other_key_frame: pandas.DataFrame, mode: JoinMode
|
|
24
|
+
) -> tuple[NDArray[numpy.intp], NDArray[numpy.intp]]:
|
|
25
|
+
"""
|
|
26
|
+
Return the row numbers of both Tables that each row of a join puts side by side.
|
|
27
|
+
|
|
28
|
+
The rows of the joined Table come first, in their order, each with its matches in the order of the other Table,
|
|
29
|
+
then the unmatched rows of the other Table, in their order. A row with a missing key never matches.
|
|
30
|
+
|
|
31
|
+
.. versionadded:: 0.1.0
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
key_frame
|
|
36
|
+
The key columns of the joined Table.
|
|
37
|
+
other_key_frame
|
|
38
|
+
The key columns of the other Table, of the same names and types.
|
|
39
|
+
mode
|
|
40
|
+
Which rows are kept.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
tuple[NDArray[numpy.intp], NDArray[numpy.intp]]
|
|
45
|
+
The row number of each Table for each row of the result, -1 where a Table has no row.
|
|
46
|
+
|
|
47
|
+
Examples
|
|
48
|
+
--------
|
|
49
|
+
>>> import pandas
|
|
50
|
+
>>> import numdaplot as ndp
|
|
51
|
+
>>> from numdaplot.tables.joining.joined_rows import pair_rows
|
|
52
|
+
>>> key_frame = pandas.DataFrame({"id": [1, 2, None]})
|
|
53
|
+
>>> other_key_frame = pandas.DataFrame({"id": [3, 1]})
|
|
54
|
+
>>> pair_rows(key_frame, other_key_frame, ndp.JoinMode.OUTER)
|
|
55
|
+
(array([ 0, 1, 2, -1]), array([ 1, -1, -1, 0]))
|
|
56
|
+
"""
|
|
57
|
+
rows, other_rows = match_rows(key_frame, other_key_frame)
|
|
58
|
+
if mode in KEEPS_UNMATCHED_ROWS:
|
|
59
|
+
row_count = len(key_frame)
|
|
60
|
+
rows, other_rows = add_unmatched_rows(rows, other_rows, row_count)
|
|
61
|
+
|
|
62
|
+
if mode in KEEPS_UNMATCHED_OTHER_ROWS:
|
|
63
|
+
other_row_count = len(other_key_frame)
|
|
64
|
+
other_rows, rows = add_unmatched_other_rows(other_rows, rows, other_row_count)
|
|
65
|
+
|
|
66
|
+
return rows, other_rows
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def match_rows(
|
|
70
|
+
key_frame: pandas.DataFrame, other_key_frame: pandas.DataFrame
|
|
71
|
+
) -> tuple[NDArray[numpy.intp], NDArray[numpy.intp]]:
|
|
72
|
+
"""
|
|
73
|
+
Return the pairs of rows whose keys are all present and equal, sorted by row of the joined Table.
|
|
74
|
+
|
|
75
|
+
.. versionadded:: 0.1.0
|
|
76
|
+
|
|
77
|
+
Parameters
|
|
78
|
+
----------
|
|
79
|
+
key_frame
|
|
80
|
+
The key columns of the joined Table.
|
|
81
|
+
other_key_frame
|
|
82
|
+
The key columns of the other Table, of the same names and types.
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
tuple[NDArray[numpy.intp], NDArray[numpy.intp]]
|
|
87
|
+
The row number in each Table of each pair.
|
|
88
|
+
|
|
89
|
+
Examples
|
|
90
|
+
--------
|
|
91
|
+
>>> import pandas
|
|
92
|
+
>>> from numdaplot.tables.joining.joined_rows import match_rows
|
|
93
|
+
>>> match_rows(pandas.DataFrame({"id": [1, 1, None]}), pandas.DataFrame({"id": [1, None]}))
|
|
94
|
+
(array([0, 1]), array([0, 0]))
|
|
95
|
+
"""
|
|
96
|
+
key_count = len(key_frame.columns)
|
|
97
|
+
key_labels = list(range(key_count))
|
|
98
|
+
row_label = key_count
|
|
99
|
+
other_row_label = key_count + 1
|
|
100
|
+
numbered_keys = number_present_rows(key_frame, row_label)
|
|
101
|
+
other_numbered_keys = number_present_rows(other_key_frame, other_row_label)
|
|
102
|
+
merged_rows = numbered_keys.merge(other_numbered_keys, how=INNER_MERGE, on=key_labels)
|
|
103
|
+
row_column = merged_rows[row_label]
|
|
104
|
+
other_row_column = merged_rows[other_row_label]
|
|
105
|
+
merged_row_numbers = row_column.to_numpy(dtype=ROW_DTYPE)
|
|
106
|
+
merged_other_row_numbers = other_row_column.to_numpy(dtype=ROW_DTYPE)
|
|
107
|
+
# numpy.lexsort sorts by the last array first.
|
|
108
|
+
pair_order = numpy.lexsort((merged_other_row_numbers, merged_row_numbers))
|
|
109
|
+
rows = merged_row_numbers[pair_order]
|
|
110
|
+
other_rows = merged_other_row_numbers[pair_order]
|
|
111
|
+
|
|
112
|
+
return rows, other_rows
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def number_present_rows(key_frame: pandas.DataFrame, row_label: int) -> pandas.DataFrame:
|
|
116
|
+
"""
|
|
117
|
+
Return the rows whose keys are all present, with their row numbers after the keys.
|
|
118
|
+
|
|
119
|
+
The keys are labeled by their position, so that no key name can meet the label of the row numbers.
|
|
120
|
+
|
|
121
|
+
.. versionadded:: 0.1.0
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
key_frame
|
|
126
|
+
The key columns of a Table.
|
|
127
|
+
row_label
|
|
128
|
+
The label of the row numbers, after the labels of the keys.
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
pandas.DataFrame
|
|
133
|
+
The keys labeled 0, 1... and the row numbers labeled ``row_label``.
|
|
134
|
+
|
|
135
|
+
Examples
|
|
136
|
+
--------
|
|
137
|
+
>>> import pandas
|
|
138
|
+
>>> from numdaplot.tables.joining.joined_rows import number_present_rows
|
|
139
|
+
>>> number_present_rows(pandas.DataFrame({"id": [1, None, 3]}), 1)[1].tolist()
|
|
140
|
+
[0, 2]
|
|
141
|
+
"""
|
|
142
|
+
key_count = len(key_frame.columns)
|
|
143
|
+
row_count = len(key_frame)
|
|
144
|
+
missing_keys = key_frame.isna()
|
|
145
|
+
has_missing_key = missing_keys.any(axis=ROWS_AXIS)
|
|
146
|
+
missing_rows = has_missing_key.to_numpy()
|
|
147
|
+
present_rows = ~missing_rows
|
|
148
|
+
row_numbers = numpy.arange(row_count, dtype=ROW_DTYPE)
|
|
149
|
+
numbered_frame = key_frame.copy()
|
|
150
|
+
numbered_frame.columns = pandas.RangeIndex(key_count)
|
|
151
|
+
numbered_frame[row_label] = row_numbers
|
|
152
|
+
present_frame = numbered_frame[present_rows]
|
|
153
|
+
|
|
154
|
+
return present_frame
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def add_unmatched_rows(
|
|
158
|
+
rows: NDArray[numpy.intp], other_rows: NDArray[numpy.intp], row_count: int
|
|
159
|
+
) -> tuple[NDArray[numpy.intp], NDArray[numpy.intp]]:
|
|
160
|
+
"""
|
|
161
|
+
Return the pairs of rows with each unmatched row of the joined Table placed at its row, without other row.
|
|
162
|
+
|
|
163
|
+
.. versionadded:: 0.1.0
|
|
164
|
+
|
|
165
|
+
Parameters
|
|
166
|
+
----------
|
|
167
|
+
rows
|
|
168
|
+
The rows of the joined Table of each pair, sorted.
|
|
169
|
+
other_rows
|
|
170
|
+
The rows of the other Table of each pair.
|
|
171
|
+
row_count
|
|
172
|
+
The number of rows of the joined Table.
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
tuple[NDArray[numpy.intp], NDArray[numpy.intp]]
|
|
177
|
+
Every row of the joined Table in its order, -1 as other row where it has no match.
|
|
178
|
+
|
|
179
|
+
Examples
|
|
180
|
+
--------
|
|
181
|
+
>>> import numpy
|
|
182
|
+
>>> from numdaplot.tables.joining.joined_rows import add_unmatched_rows
|
|
183
|
+
>>> add_unmatched_rows(numpy.array([1, 1]), numpy.array([0, 2]), 3)
|
|
184
|
+
(array([0, 1, 1, 2]), array([-1, 0, 2, -1]))
|
|
185
|
+
"""
|
|
186
|
+
all_rows = numpy.arange(row_count, dtype=ROW_DTYPE)
|
|
187
|
+
unmatched_rows = numpy.setdiff1d(all_rows, rows)
|
|
188
|
+
unmatched_count = len(unmatched_rows)
|
|
189
|
+
no_other_rows = numpy.full(unmatched_count, NO_ROW, dtype=ROW_DTYPE)
|
|
190
|
+
joined_rows = numpy.concatenate([rows, unmatched_rows])
|
|
191
|
+
joined_other_rows = numpy.concatenate([other_rows, no_other_rows])
|
|
192
|
+
row_order = numpy.argsort(joined_rows, kind=STABLE_SORT)
|
|
193
|
+
ordered_rows = joined_rows[row_order]
|
|
194
|
+
ordered_other_rows = joined_other_rows[row_order]
|
|
195
|
+
|
|
196
|
+
return ordered_rows, ordered_other_rows
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def add_unmatched_other_rows(
|
|
200
|
+
other_rows: NDArray[numpy.intp], rows: NDArray[numpy.intp], other_row_count: int
|
|
201
|
+
) -> tuple[NDArray[numpy.intp], NDArray[numpy.intp]]:
|
|
202
|
+
"""
|
|
203
|
+
Return the pairs of rows followed by the unmatched rows of the other Table, in their order, without row.
|
|
204
|
+
|
|
205
|
+
.. versionadded:: 0.1.0
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
other_rows
|
|
210
|
+
The rows of the other Table of each pair.
|
|
211
|
+
rows
|
|
212
|
+
The rows of the joined Table of each pair.
|
|
213
|
+
other_row_count
|
|
214
|
+
The number of rows of the other Table.
|
|
215
|
+
|
|
216
|
+
Returns
|
|
217
|
+
-------
|
|
218
|
+
tuple[NDArray[numpy.intp], NDArray[numpy.intp]]
|
|
219
|
+
The rows of the other Table, then the rows of the joined Table, -1 for each unmatched row added.
|
|
220
|
+
|
|
221
|
+
Examples
|
|
222
|
+
--------
|
|
223
|
+
>>> import numpy
|
|
224
|
+
>>> from numdaplot.tables.joining.joined_rows import add_unmatched_other_rows
|
|
225
|
+
>>> add_unmatched_other_rows(numpy.array([1]), numpy.array([0]), 3)
|
|
226
|
+
(array([1, 0, 2]), array([ 0, -1, -1]))
|
|
227
|
+
"""
|
|
228
|
+
all_other_rows = numpy.arange(other_row_count, dtype=ROW_DTYPE)
|
|
229
|
+
unmatched_other_rows = numpy.setdiff1d(all_other_rows, other_rows)
|
|
230
|
+
unmatched_count = len(unmatched_other_rows)
|
|
231
|
+
no_rows = numpy.full(unmatched_count, NO_ROW, dtype=ROW_DTYPE)
|
|
232
|
+
joined_other_rows = numpy.concatenate([other_rows, unmatched_other_rows])
|
|
233
|
+
joined_rows = numpy.concatenate([rows, no_rows])
|
|
234
|
+
|
|
235
|
+
return joined_other_rows, joined_rows
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""
|
|
2
|
+
How close the types of the keys of a join must be.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from enum import Enum, auto
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class KeyTypes(Enum):
|
|
11
|
+
"""
|
|
12
|
+
How close the types of the two columns of each key of a join must be, used by ``Join``.
|
|
13
|
+
|
|
14
|
+
A ``DATE`` key never matches a ``DATETIME`` key, and datetimes must have the same time zone on both sides.
|
|
15
|
+
|
|
16
|
+
.. versionadded:: 0.1.0
|
|
17
|
+
|
|
18
|
+
Examples
|
|
19
|
+
--------
|
|
20
|
+
>>> import numdaplot as ndp
|
|
21
|
+
>>> accidents = ndp.Table.from_arrays({"id": ndp.Array.from_list([1, 2])})
|
|
22
|
+
>>> users = ndp.Table.from_arrays({"id": ndp.Array.from_list([1.0, 2.0]), "age": ndp.Array.from_list([34, 51])})
|
|
23
|
+
>>> accidents.join(ndp.Join(other=users, keys=["id"], key_types=ndp.KeyTypes.SAME_FAMILY)).column_types
|
|
24
|
+
{'id': <Type.FLOAT64: 10>, 'age': <Type.INT64: 4>}
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
SAME_FAMILY = auto()
|
|
28
|
+
"""
|
|
29
|
+
Both columns hold numbers, texts, booleans, dates, datetimes, durations or times of day. Default value.
|
|
30
|
+
|
|
31
|
+
The key of the result takes the type holding both: ``INT64`` and ``FLOAT64`` give ``FLOAT64``, ``TEXT`` and
|
|
32
|
+
``CATEGORY`` give ``TEXT``.
|
|
33
|
+
|
|
34
|
+
Examples
|
|
35
|
+
--------
|
|
36
|
+
>>> import numdaplot as ndp
|
|
37
|
+
>>> accidents = ndp.Table.from_arrays({"id": ndp.Array.from_list([1, 2])})
|
|
38
|
+
>>> users = ndp.Table.from_arrays({"id": ndp.Array.from_list([1.0, 2.0]), "age": ndp.Array.from_list([34, 51])})
|
|
39
|
+
>>> accidents.join(ndp.Join(other=users, keys=["id"], key_types=ndp.KeyTypes.SAME_FAMILY)).column_types
|
|
40
|
+
{'id': <Type.FLOAT64: 10>, 'age': <Type.INT64: 4>}
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
SAME_TYPE = auto()
|
|
44
|
+
"""
|
|
45
|
+
Both columns have the same type: ``INT64`` and ``FLOAT64`` are refused.
|
|
46
|
+
|
|
47
|
+
Examples
|
|
48
|
+
--------
|
|
49
|
+
>>> import numdaplot as ndp
|
|
50
|
+
>>> accidents = ndp.Table.from_arrays({"id": ndp.Array.from_list([1, 2])})
|
|
51
|
+
>>> users = ndp.Table.from_arrays({"id": ndp.Array.from_list([1.0, 2.0])})
|
|
52
|
+
>>> try:
|
|
53
|
+
... accidents.join(ndp.Join(other=users, keys=["id"], key_types=ndp.KeyTypes.SAME_TYPE))
|
|
54
|
+
... except ndp.IncompatibleTypesError as error:
|
|
55
|
+
... print(error)
|
|
56
|
+
Cannot apply Join to the INT64 column 'id' and FLOAT64.
|
|
57
|
+
"""
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""
|
|
2
|
+
How many times each key may appear in the Tables of a join.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from enum import Enum, auto
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Relation(Enum):
|
|
11
|
+
"""
|
|
12
|
+
How many times each key may appear in the two Tables of a join, checked by ``Join`` before joining.
|
|
13
|
+
|
|
14
|
+
The first word is for the left Table, the one joined, the second for the right Table, the other one. With
|
|
15
|
+
several keys, their combination is checked. Rows with a missing key are not checked, as they never match.
|
|
16
|
+
|
|
17
|
+
.. versionadded:: 0.1.0
|
|
18
|
+
|
|
19
|
+
Examples
|
|
20
|
+
--------
|
|
21
|
+
>>> import numdaplot as ndp
|
|
22
|
+
>>> accidents = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 102])})
|
|
23
|
+
>>> users = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 101, 102])})
|
|
24
|
+
>>> accidents.join(ndp.Join(other=users, keys=["Num_Acc"], relation=ndp.Relation.ONE_TO_MANY)).row_count
|
|
25
|
+
3
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
MANY_TO_MANY = auto()
|
|
29
|
+
"""
|
|
30
|
+
Nothing is checked: each key may appear several times on both sides. Default value.
|
|
31
|
+
|
|
32
|
+
Examples
|
|
33
|
+
--------
|
|
34
|
+
>>> import numdaplot as ndp
|
|
35
|
+
>>> accidents = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 101])})
|
|
36
|
+
>>> users = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 101])})
|
|
37
|
+
>>> accidents.join(ndp.Join(other=users, keys=["Num_Acc"], relation=ndp.Relation.MANY_TO_MANY)).row_count
|
|
38
|
+
4
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
ONE_TO_ONE = auto()
|
|
42
|
+
"""
|
|
43
|
+
Each key appears at most once in each Table.
|
|
44
|
+
|
|
45
|
+
Examples
|
|
46
|
+
--------
|
|
47
|
+
>>> import numdaplot as ndp
|
|
48
|
+
>>> accidents = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 102])})
|
|
49
|
+
>>> places = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 102])})
|
|
50
|
+
>>> accidents.join(ndp.Join(other=places, keys=["Num_Acc"], relation=ndp.Relation.ONE_TO_ONE)).row_count
|
|
51
|
+
2
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
ONE_TO_MANY = auto()
|
|
55
|
+
"""
|
|
56
|
+
Each key appears at most once in the left Table, and any number of times in the right Table.
|
|
57
|
+
|
|
58
|
+
Examples
|
|
59
|
+
--------
|
|
60
|
+
>>> import numdaplot as ndp
|
|
61
|
+
>>> accidents = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 102])})
|
|
62
|
+
>>> users = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 101, 102])})
|
|
63
|
+
>>> accidents.join(ndp.Join(other=users, keys=["Num_Acc"], relation=ndp.Relation.ONE_TO_MANY)).row_count
|
|
64
|
+
3
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
MANY_TO_ONE = auto()
|
|
68
|
+
"""
|
|
69
|
+
Each key appears any number of times in the left Table, and at most once in the right Table.
|
|
70
|
+
|
|
71
|
+
Examples
|
|
72
|
+
--------
|
|
73
|
+
>>> import numdaplot as ndp
|
|
74
|
+
>>> users = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 101, 102])})
|
|
75
|
+
>>> accidents = ndp.Table.from_arrays({"Num_Acc": ndp.Array.from_list([101, 102])})
|
|
76
|
+
>>> users.join(ndp.Join(other=accidents, keys=["Num_Acc"], relation=ndp.Relation.MANY_TO_ONE)).row_count
|
|
77
|
+
3
|
|
78
|
+
"""
|