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,459 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Normalization of a pandas DataFrame into the storage of a Table.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Any, cast
|
|
9
|
+
|
|
10
|
+
import numpy
|
|
11
|
+
import pandas
|
|
12
|
+
from pandas.api.types import infer_dtype
|
|
13
|
+
|
|
14
|
+
from numdaplot.data_types.numpy_mapping import from_numpy_dtype
|
|
15
|
+
from numdaplot.data_types.pandas_mapping import TYPES_BY_PANDAS_NAME, from_pandas_dtype, to_pandas_dtype
|
|
16
|
+
from numdaplot.data_types.time_of_day import holds_only_times
|
|
17
|
+
from numdaplot.data_types.type import Type
|
|
18
|
+
from numdaplot.errors.unsupported_index_error import UnsupportedIndexError
|
|
19
|
+
from numdaplot.tables.columns.column_names import require_column_names
|
|
20
|
+
from numdaplot.tables.frames.column import Column
|
|
21
|
+
from numdaplot.tables.frames.time_columns import is_time_column, read_object_values, store_time_column
|
|
22
|
+
from numdaplot.tables.frames.time_range_errors import TimeRangeErrors
|
|
23
|
+
from numdaplot.tables.frames.time_zones import normalize_time_zone_column
|
|
24
|
+
|
|
25
|
+
INFERRED_TYPES = {
|
|
26
|
+
"integer": Type.INT64,
|
|
27
|
+
"floating": Type.FLOAT64,
|
|
28
|
+
"mixed-integer-float": Type.FLOAT64,
|
|
29
|
+
"decimal": Type.FLOAT64,
|
|
30
|
+
"boolean": Type.BOOL,
|
|
31
|
+
"timedelta": Type.DURATION,
|
|
32
|
+
}
|
|
33
|
+
MOMENT_KINDS = frozenset({"date", "datetime"})
|
|
34
|
+
INTEGER_KINDS = frozenset({"i", "u"})
|
|
35
|
+
BOOLEAN_KIND = "b"
|
|
36
|
+
DECIMAL_KIND = "f"
|
|
37
|
+
DATETIME_KIND = "M"
|
|
38
|
+
DURATION_KIND = "m"
|
|
39
|
+
TEXT_INFERRED_KINDS = frozenset({"string", "empty"})
|
|
40
|
+
DATETIME_DTYPE = "datetime64[ns]"
|
|
41
|
+
DURATION_DTYPE = "timedelta64[ns]"
|
|
42
|
+
PYTHON_OBJECT_DTYPE = numpy.dtype(object)
|
|
43
|
+
TABLE_CREATION_OPERATION = "Table creation"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def normalize_frame(frame: pandas.DataFrame) -> pandas.DataFrame:
|
|
47
|
+
"""
|
|
48
|
+
Return a DataFrame stored the way a Table stores its columns.
|
|
49
|
+
|
|
50
|
+
.. versionadded:: 0.1.0
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
frame
|
|
55
|
+
Any DataFrame, read from a file or given by the user. It is not changed.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
pandas.DataFrame
|
|
60
|
+
A new DataFrame numbered from 0, whose columns use the dtypes given by ``to_pandas_dtype``.
|
|
61
|
+
|
|
62
|
+
Raises
|
|
63
|
+
------
|
|
64
|
+
InvalidColumnNameError
|
|
65
|
+
When a column name is not a non-empty text.
|
|
66
|
+
DuplicateColumnError
|
|
67
|
+
When a column name appears twice.
|
|
68
|
+
UnsupportedIndexError
|
|
69
|
+
When the index holds anything else than the row numbers 0, 1, 2...
|
|
70
|
+
UnsupportedTypeError
|
|
71
|
+
When a column has a type numdaplot does not support, such as complex numbers.
|
|
72
|
+
|
|
73
|
+
Examples
|
|
74
|
+
--------
|
|
75
|
+
>>> import pandas
|
|
76
|
+
>>> from numdaplot.tables.frames.frame_normalization import normalize_frame
|
|
77
|
+
>>> normalize_frame(pandas.DataFrame({"count": [1, 2]})).dtypes.tolist()
|
|
78
|
+
[Int64Dtype()]
|
|
79
|
+
"""
|
|
80
|
+
raw_names = list(frame.columns)
|
|
81
|
+
require_column_names(raw_names)
|
|
82
|
+
require_plain_index(frame.index)
|
|
83
|
+
column_names = [str(raw_name) for raw_name in raw_names]
|
|
84
|
+
normalized_columns = dict[str, Column]()
|
|
85
|
+
|
|
86
|
+
for column_name in column_names:
|
|
87
|
+
column = frame[column_name]
|
|
88
|
+
with TimeRangeErrors(TABLE_CREATION_OPERATION, column_name):
|
|
89
|
+
normalized_column = normalize_column(column)
|
|
90
|
+
|
|
91
|
+
normalized_columns[column_name] = normalized_column
|
|
92
|
+
|
|
93
|
+
row_count = len(frame)
|
|
94
|
+
row_numbers = pandas.RangeIndex(row_count)
|
|
95
|
+
normalized_frame = pandas.DataFrame(normalized_columns, index=row_numbers)
|
|
96
|
+
|
|
97
|
+
return normalized_frame
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def require_plain_index(index: pandas.Index) -> None:
|
|
101
|
+
"""
|
|
102
|
+
Check that an index only holds the row numbers 0, 1, 2...
|
|
103
|
+
|
|
104
|
+
.. versionadded:: 0.1.0
|
|
105
|
+
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
index
|
|
109
|
+
The index of a DataFrame.
|
|
110
|
+
|
|
111
|
+
Raises
|
|
112
|
+
------
|
|
113
|
+
UnsupportedIndexError
|
|
114
|
+
When the index holds other values, such as city names.
|
|
115
|
+
|
|
116
|
+
Examples
|
|
117
|
+
--------
|
|
118
|
+
>>> import numdaplot as ndp
|
|
119
|
+
>>> import pandas
|
|
120
|
+
>>> from numdaplot.tables.frames.frame_normalization import require_plain_index
|
|
121
|
+
>>> try:
|
|
122
|
+
... require_plain_index(pandas.Index(["Paris", "Lyon"]))
|
|
123
|
+
... except ndp.UnsupportedIndexError as error:
|
|
124
|
+
... print(error)
|
|
125
|
+
A Table has no index, call reset_index() on the pandas DataFrame first to keep its index as a column.
|
|
126
|
+
"""
|
|
127
|
+
row_count = len(index)
|
|
128
|
+
row_numbers = pandas.RangeIndex(row_count)
|
|
129
|
+
is_plain = index.equals(row_numbers)
|
|
130
|
+
if not is_plain:
|
|
131
|
+
raise UnsupportedIndexError()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def normalize_column(column: Column) -> Column:
|
|
135
|
+
"""
|
|
136
|
+
Return a column stored with the pandas dtype of its numdaplot type.
|
|
137
|
+
|
|
138
|
+
.. versionadded:: 0.1.0
|
|
139
|
+
|
|
140
|
+
Parameters
|
|
141
|
+
----------
|
|
142
|
+
column
|
|
143
|
+
Any pandas column.
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
pandas.Series
|
|
148
|
+
The column itself when its dtype is already one a Table uses, otherwise a converted copy.
|
|
149
|
+
Python objects become integers, decimals or booleans when they all are, and texts otherwise.
|
|
150
|
+
|
|
151
|
+
Raises
|
|
152
|
+
------
|
|
153
|
+
UnsupportedTypeError
|
|
154
|
+
When the column has a type numdaplot does not support, such as complex numbers or
|
|
155
|
+
datetimes in a fixed offset instead of a time zone.
|
|
156
|
+
|
|
157
|
+
Examples
|
|
158
|
+
--------
|
|
159
|
+
>>> import pandas
|
|
160
|
+
>>> from numdaplot.tables.frames.frame_normalization import normalize_column
|
|
161
|
+
>>> text_column = normalize_column(pandas.Series(["a", None], dtype=object))
|
|
162
|
+
>>> str(text_column.dtype)
|
|
163
|
+
'string'
|
|
164
|
+
"""
|
|
165
|
+
dtype_name = str(column.dtype)
|
|
166
|
+
if dtype_name in TYPES_BY_PANDAS_NAME:
|
|
167
|
+
stored_column = normalize_categories(column)
|
|
168
|
+
return stored_column
|
|
169
|
+
|
|
170
|
+
converted_column = convert_column_dtype(column)
|
|
171
|
+
from_pandas_dtype(converted_column.dtype)
|
|
172
|
+
|
|
173
|
+
return converted_column
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def convert_column_dtype(column: Column) -> Column:
|
|
177
|
+
"""
|
|
178
|
+
Return a column converted to the dtype a Table uses for its kind of values.
|
|
179
|
+
|
|
180
|
+
.. versionadded:: 0.1.0
|
|
181
|
+
|
|
182
|
+
Parameters
|
|
183
|
+
----------
|
|
184
|
+
column
|
|
185
|
+
A column whose dtype is not one a Table uses.
|
|
186
|
+
|
|
187
|
+
Returns
|
|
188
|
+
-------
|
|
189
|
+
pandas.Series
|
|
190
|
+
The converted column, or the column itself when no conversion applies.
|
|
191
|
+
|
|
192
|
+
Raises
|
|
193
|
+
------
|
|
194
|
+
UnsupportedTypeError
|
|
195
|
+
When the column holds datetimes in a fixed offset instead of a time zone.
|
|
196
|
+
|
|
197
|
+
Examples
|
|
198
|
+
--------
|
|
199
|
+
>>> import numpy
|
|
200
|
+
>>> import pandas
|
|
201
|
+
>>> from numdaplot.tables.frames.frame_normalization import convert_column_dtype
|
|
202
|
+
>>> convert_column_dtype(pandas.Series([1, 2], dtype=numpy.int32)).dtype
|
|
203
|
+
Int32Dtype()
|
|
204
|
+
"""
|
|
205
|
+
column_dtype = column.dtype
|
|
206
|
+
dtype_kind = column_dtype.kind
|
|
207
|
+
if isinstance(column_dtype, pandas.DatetimeTZDtype):
|
|
208
|
+
time_zone_column = normalize_time_zone_column(column)
|
|
209
|
+
return time_zone_column
|
|
210
|
+
|
|
211
|
+
if isinstance(column_dtype, pandas.StringDtype):
|
|
212
|
+
text_column = convert_to_type(column, Type.TEXT)
|
|
213
|
+
return text_column
|
|
214
|
+
|
|
215
|
+
if dtype_kind == DECIMAL_KIND:
|
|
216
|
+
decimal_column = convert_decimals(column)
|
|
217
|
+
return decimal_column
|
|
218
|
+
|
|
219
|
+
if dtype_kind == DATETIME_KIND:
|
|
220
|
+
datetime_column = column.astype(DATETIME_DTYPE)
|
|
221
|
+
return datetime_column
|
|
222
|
+
|
|
223
|
+
if is_time_column(column):
|
|
224
|
+
return column
|
|
225
|
+
|
|
226
|
+
if dtype_kind == DURATION_KIND:
|
|
227
|
+
duration_column = column.astype(DURATION_DTYPE)
|
|
228
|
+
return duration_column
|
|
229
|
+
|
|
230
|
+
is_numpy_dtype = isinstance(column_dtype, numpy.dtype)
|
|
231
|
+
if not is_numpy_dtype:
|
|
232
|
+
return column
|
|
233
|
+
|
|
234
|
+
converted_column = convert_numpy_column(column)
|
|
235
|
+
|
|
236
|
+
return converted_column
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def convert_decimals(column: Column) -> Column:
|
|
240
|
+
"""
|
|
241
|
+
Return a decimal column stored as numpy decimals, with NaN as missing value.
|
|
242
|
+
|
|
243
|
+
.. versionadded:: 0.1.0
|
|
244
|
+
|
|
245
|
+
Parameters
|
|
246
|
+
----------
|
|
247
|
+
column
|
|
248
|
+
A decimal column, such as the pandas ``Float64`` dtype that marks missing values with ``pd.NA``.
|
|
249
|
+
|
|
250
|
+
Returns
|
|
251
|
+
-------
|
|
252
|
+
pandas.Series
|
|
253
|
+
The column with the numpy decimal dtype of the same size.
|
|
254
|
+
|
|
255
|
+
Examples
|
|
256
|
+
--------
|
|
257
|
+
>>> import pandas
|
|
258
|
+
>>> from numdaplot.tables.frames.frame_normalization import convert_decimals
|
|
259
|
+
>>> convert_decimals(pandas.Series([1.5, None], dtype="Float64")).tolist()
|
|
260
|
+
[1.5, nan]
|
|
261
|
+
"""
|
|
262
|
+
dtype_name = str(column.dtype)
|
|
263
|
+
numpy_dtype_name = dtype_name.lower()
|
|
264
|
+
decimal_values = column.to_numpy(dtype=numpy_dtype_name, na_value=numpy.nan)
|
|
265
|
+
decimal_column = pandas.Series(decimal_values, index=column.index)
|
|
266
|
+
|
|
267
|
+
return decimal_column
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def convert_numpy_column(column: Column) -> Column:
|
|
271
|
+
"""
|
|
272
|
+
Return a numpy integer, boolean or object column stored with the dtype a Table uses.
|
|
273
|
+
|
|
274
|
+
.. versionadded:: 0.1.0
|
|
275
|
+
|
|
276
|
+
Parameters
|
|
277
|
+
----------
|
|
278
|
+
column
|
|
279
|
+
A column with a numpy dtype.
|
|
280
|
+
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
pandas.Series
|
|
284
|
+
Integers and booleans in the pandas dtypes that accept missing values, Python objects
|
|
285
|
+
as guessed by ``infer_object_column``, any other column unchanged.
|
|
286
|
+
|
|
287
|
+
Examples
|
|
288
|
+
--------
|
|
289
|
+
>>> import pandas
|
|
290
|
+
>>> from numdaplot.tables.frames.frame_normalization import convert_numpy_column
|
|
291
|
+
>>> convert_numpy_column(pandas.Series([True, False])).dtype
|
|
292
|
+
BooleanDtype
|
|
293
|
+
"""
|
|
294
|
+
dtype_kind = column.dtype.kind
|
|
295
|
+
if dtype_kind in INTEGER_KINDS:
|
|
296
|
+
integer_dtype = cast(numpy.dtype[Any], column.dtype)
|
|
297
|
+
integer_type = from_numpy_dtype(integer_dtype)
|
|
298
|
+
integer_column = convert_to_type(column, integer_type)
|
|
299
|
+
return integer_column
|
|
300
|
+
|
|
301
|
+
if dtype_kind == BOOLEAN_KIND:
|
|
302
|
+
boolean_column = convert_to_type(column, Type.BOOL)
|
|
303
|
+
return boolean_column
|
|
304
|
+
|
|
305
|
+
if column.dtype == PYTHON_OBJECT_DTYPE:
|
|
306
|
+
object_column = infer_object_column(column)
|
|
307
|
+
return object_column
|
|
308
|
+
|
|
309
|
+
return column
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def infer_object_column(column: Column) -> Column:
|
|
313
|
+
"""
|
|
314
|
+
Return a column of Python objects stored with the type its present values share.
|
|
315
|
+
|
|
316
|
+
.. versionadded:: 0.1.0
|
|
317
|
+
|
|
318
|
+
Parameters
|
|
319
|
+
----------
|
|
320
|
+
column
|
|
321
|
+
A column of Python objects.
|
|
322
|
+
|
|
323
|
+
Returns
|
|
324
|
+
-------
|
|
325
|
+
pandas.Series
|
|
326
|
+
``INT64`` when every present value is an integer, ``FLOAT64`` for decimals or integers and decimals,
|
|
327
|
+
``BOOL`` for booleans, ``DATE`` for dates, ``DATETIME`` for datetimes or dates and datetimes, ``DURATION``
|
|
328
|
+
for durations, and ``TEXT`` for anything else, each value then written as a text.
|
|
329
|
+
|
|
330
|
+
Examples
|
|
331
|
+
--------
|
|
332
|
+
>>> import pandas
|
|
333
|
+
>>> from numdaplot.tables.frames.frame_normalization import infer_object_column
|
|
334
|
+
>>> infer_object_column(pandas.Series([1, None, 3], dtype=object)).tolist()
|
|
335
|
+
[1, <NA>, 3]
|
|
336
|
+
"""
|
|
337
|
+
object_values = read_object_values(column)
|
|
338
|
+
if holds_only_times(object_values):
|
|
339
|
+
time_column = store_time_column(column)
|
|
340
|
+
return time_column
|
|
341
|
+
|
|
342
|
+
inferred_kind = infer_dtype(column, skipna=True)
|
|
343
|
+
target_type = INFERRED_TYPES.get(inferred_kind, Type.TEXT)
|
|
344
|
+
if inferred_kind in MOMENT_KINDS:
|
|
345
|
+
target_type = find_moment_type(column)
|
|
346
|
+
|
|
347
|
+
converted_column = convert_to_type(column, target_type)
|
|
348
|
+
|
|
349
|
+
return converted_column
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def find_moment_type(column: Column) -> Type:
|
|
353
|
+
"""
|
|
354
|
+
Return the type of a column of Python dates and datetimes.
|
|
355
|
+
|
|
356
|
+
.. versionadded:: 0.1.0
|
|
357
|
+
|
|
358
|
+
Parameters
|
|
359
|
+
----------
|
|
360
|
+
column
|
|
361
|
+
A column of Python objects, each present value being a date or a datetime.
|
|
362
|
+
|
|
363
|
+
Returns
|
|
364
|
+
-------
|
|
365
|
+
Type
|
|
366
|
+
``DATE`` for dates only, ``DATETIME`` as soon as a value is a datetime, a date then counting as midnight,
|
|
367
|
+
and ``TEXT`` as soon as a datetime has a time zone, as a column holds a single zone.
|
|
368
|
+
|
|
369
|
+
Examples
|
|
370
|
+
--------
|
|
371
|
+
>>> from datetime import date, datetime
|
|
372
|
+
>>> import pandas
|
|
373
|
+
>>> from numdaplot.tables.frames.frame_normalization import find_moment_type
|
|
374
|
+
>>> find_moment_type(pandas.Series([date(2026, 1, 31)], dtype=object))
|
|
375
|
+
<Type.DATE: 14>
|
|
376
|
+
>>> find_moment_type(pandas.Series([date(2026, 1, 31), datetime(2026, 1, 31, 8)], dtype=object))
|
|
377
|
+
<Type.DATETIME: 15>
|
|
378
|
+
"""
|
|
379
|
+
present_column = column.dropna()
|
|
380
|
+
moments = present_column.tolist()
|
|
381
|
+
moment_type = Type.DATE
|
|
382
|
+
|
|
383
|
+
for moment in moments:
|
|
384
|
+
if isinstance(moment, datetime):
|
|
385
|
+
moment_type = Type.DATETIME
|
|
386
|
+
if moment.tzinfo is not None:
|
|
387
|
+
return Type.TEXT
|
|
388
|
+
|
|
389
|
+
return moment_type
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def normalize_categories(column: Column) -> Column:
|
|
393
|
+
"""
|
|
394
|
+
Return a column whose categories, if it has any, are texts.
|
|
395
|
+
|
|
396
|
+
.. versionadded:: 0.1.0
|
|
397
|
+
|
|
398
|
+
Parameters
|
|
399
|
+
----------
|
|
400
|
+
column
|
|
401
|
+
A column stored with a dtype a Table uses.
|
|
402
|
+
|
|
403
|
+
Returns
|
|
404
|
+
-------
|
|
405
|
+
pandas.Series
|
|
406
|
+
The column itself, or a category column of texts when its categories are other values.
|
|
407
|
+
|
|
408
|
+
Examples
|
|
409
|
+
--------
|
|
410
|
+
>>> import pandas
|
|
411
|
+
>>> from numdaplot.tables.frames.frame_normalization import normalize_categories
|
|
412
|
+
>>> categories = normalize_categories(pandas.Series([1, 2], dtype="category"))
|
|
413
|
+
>>> categories.tolist()
|
|
414
|
+
['1', '2']
|
|
415
|
+
"""
|
|
416
|
+
if not isinstance(column.dtype, pandas.CategoricalDtype):
|
|
417
|
+
return column
|
|
418
|
+
|
|
419
|
+
categories = column.cat.categories
|
|
420
|
+
categories_kind = infer_dtype(categories, skipna=True)
|
|
421
|
+
if categories_kind in TEXT_INFERRED_KINDS:
|
|
422
|
+
return column
|
|
423
|
+
|
|
424
|
+
text_column = convert_to_type(column, Type.TEXT)
|
|
425
|
+
category_column = convert_to_type(text_column, Type.CATEGORY)
|
|
426
|
+
|
|
427
|
+
return category_column
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def convert_to_type(column: Column, data_type: Type) -> Column:
|
|
431
|
+
"""
|
|
432
|
+
Return a column converted to the pandas dtype of a numdaplot type.
|
|
433
|
+
|
|
434
|
+
.. versionadded:: 0.1.0
|
|
435
|
+
|
|
436
|
+
Parameters
|
|
437
|
+
----------
|
|
438
|
+
column
|
|
439
|
+
Any column.
|
|
440
|
+
data_type
|
|
441
|
+
The numdaplot type to store the column as.
|
|
442
|
+
|
|
443
|
+
Returns
|
|
444
|
+
-------
|
|
445
|
+
pandas.Series
|
|
446
|
+
The converted column.
|
|
447
|
+
|
|
448
|
+
Examples
|
|
449
|
+
--------
|
|
450
|
+
>>> import pandas
|
|
451
|
+
>>> import numdaplot as ndp
|
|
452
|
+
>>> from numdaplot.tables.frames.frame_normalization import convert_to_type
|
|
453
|
+
>>> convert_to_type(pandas.Series([1, 2]), ndp.Type.TEXT).tolist()
|
|
454
|
+
['1', '2']
|
|
455
|
+
"""
|
|
456
|
+
pandas_dtype = to_pandas_dtype(data_type)
|
|
457
|
+
converted_column = column.astype(pandas_dtype)
|
|
458
|
+
|
|
459
|
+
return converted_column
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Name of the Table column in the type errors of a block.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from types import TracebackType
|
|
8
|
+
|
|
9
|
+
from numdaplot.errors.incompatible_types_error import IncompatibleTypesError
|
|
10
|
+
from numdaplot.errors.time_overflow_error import TimeOverflowError
|
|
11
|
+
from numdaplot.errors.value_conversion_error import ValueConversionError
|
|
12
|
+
from numdaplot.tables.frames.column import Column
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class NamedColumnErrors:
|
|
16
|
+
"""
|
|
17
|
+
Context adding the name of a Table column to the type errors raised by a block.
|
|
18
|
+
|
|
19
|
+
.. versionadded:: 0.1.0
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
column
|
|
24
|
+
The column the block works on. A column without name leaves the errors as they are.
|
|
25
|
+
|
|
26
|
+
Examples
|
|
27
|
+
--------
|
|
28
|
+
>>> import pandas
|
|
29
|
+
>>> import numdaplot as ndp
|
|
30
|
+
>>> from numdaplot.tables.frames.named_column_errors import NamedColumnErrors
|
|
31
|
+
>>> try:
|
|
32
|
+
... with NamedColumnErrors(pandas.Series([1.0], name="price")):
|
|
33
|
+
... raise ndp.IncompatibleTypesError("Contains", ["FLOAT64"])
|
|
34
|
+
... except ndp.IncompatibleTypesError as error:
|
|
35
|
+
... print(error)
|
|
36
|
+
Cannot apply Contains to the FLOAT64 column 'price'.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, column: Column) -> None:
|
|
40
|
+
"""
|
|
41
|
+
Keep the column of the block.
|
|
42
|
+
|
|
43
|
+
.. versionadded:: 0.1.0
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
column
|
|
48
|
+
The column the block works on.
|
|
49
|
+
"""
|
|
50
|
+
self.column = column
|
|
51
|
+
|
|
52
|
+
def __enter__(self) -> None:
|
|
53
|
+
"""
|
|
54
|
+
Start the block.
|
|
55
|
+
|
|
56
|
+
.. versionadded:: 0.1.0
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def __exit__(
|
|
60
|
+
self,
|
|
61
|
+
error_type: type[BaseException] | None,
|
|
62
|
+
error: BaseException | None,
|
|
63
|
+
traceback: TracebackType | None,
|
|
64
|
+
) -> None:
|
|
65
|
+
"""
|
|
66
|
+
Name the column in a type error of the block, which then goes on.
|
|
67
|
+
|
|
68
|
+
.. versionadded:: 0.1.0
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
error_type
|
|
73
|
+
The type of the error raised by the block, or None.
|
|
74
|
+
error
|
|
75
|
+
The error raised by the block, or None.
|
|
76
|
+
traceback
|
|
77
|
+
Its traceback, or None.
|
|
78
|
+
"""
|
|
79
|
+
column_name = self.column.name
|
|
80
|
+
if column_name is None:
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if isinstance(error, IncompatibleTypesError | TimeOverflowError | ValueConversionError):
|
|
84
|
+
column_text = str(column_name)
|
|
85
|
+
error.name_column(column_text)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Exact reading of decimals written as texts, which pandas only gives by default from version 3.1.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import Any, cast
|
|
9
|
+
|
|
10
|
+
import numpy
|
|
11
|
+
import pandas
|
|
12
|
+
from numpy.typing import NDArray
|
|
13
|
+
|
|
14
|
+
VERSION_PATTERN = r"(\d+)\.(\d+)"
|
|
15
|
+
FIRST_EXACT_VERSION = (3, 1)
|
|
16
|
+
FLOAT_PRECISION_SETTING = "float_precision"
|
|
17
|
+
ROUND_TRIP_PRECISION = "round_trip"
|
|
18
|
+
DECIMAL_KIND = "f"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def reads_exact_decimals(pandas_version: str) -> bool:
|
|
22
|
+
"""
|
|
23
|
+
Return whether a version of pandas reads the exact value of a decimal written as a text.
|
|
24
|
+
|
|
25
|
+
.. versionadded:: 0.1.0
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
pandas_version
|
|
30
|
+
The version, such as ``"3.1.0"``.
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
bool
|
|
35
|
+
True from version 3.1.
|
|
36
|
+
|
|
37
|
+
Examples
|
|
38
|
+
--------
|
|
39
|
+
>>> from numdaplot.tables.frames.pandas_decimals import reads_exact_decimals
|
|
40
|
+
>>> reads_exact_decimals("2.3.0"), reads_exact_decimals("3.1.0rc0")
|
|
41
|
+
(False, True)
|
|
42
|
+
"""
|
|
43
|
+
version_match = cast(re.Match[str], re.match(VERSION_PATTERN, pandas_version))
|
|
44
|
+
major_text, minor_text = version_match.groups()
|
|
45
|
+
major = int(major_text)
|
|
46
|
+
minor = int(minor_text)
|
|
47
|
+
is_exact = (major, minor) >= FIRST_EXACT_VERSION
|
|
48
|
+
|
|
49
|
+
return is_exact
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
READS_EXACT_DECIMALS = reads_exact_decimals(pandas.__version__)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def find_exact_csv_settings() -> dict[str, str]:
|
|
56
|
+
"""
|
|
57
|
+
Return the settings ``pandas.read_csv`` needs to read the exact value of each decimal.
|
|
58
|
+
|
|
59
|
+
.. versionadded:: 0.1.0
|
|
60
|
+
|
|
61
|
+
Returns
|
|
62
|
+
-------
|
|
63
|
+
dict[str, str]
|
|
64
|
+
The precision of the slower exact reading before pandas 3.1, nothing from then on as the setting is
|
|
65
|
+
deprecated there.
|
|
66
|
+
|
|
67
|
+
Examples
|
|
68
|
+
--------
|
|
69
|
+
>>> from numdaplot.tables.frames.pandas_decimals import find_exact_csv_settings
|
|
70
|
+
>>> settings = find_exact_csv_settings()
|
|
71
|
+
>>> settings in ({}, {"float_precision": "round_trip"})
|
|
72
|
+
True
|
|
73
|
+
"""
|
|
74
|
+
if READS_EXACT_DECIMALS:
|
|
75
|
+
return {}
|
|
76
|
+
|
|
77
|
+
return {FLOAT_PRECISION_SETTING: ROUND_TRIP_PRECISION}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def restore_exact_decimals(texts: NDArray[Any], numbers: NDArray[Any]) -> NDArray[Any]:
|
|
81
|
+
"""
|
|
82
|
+
Return numbers read by ``pandas.to_numeric``, with the exact value of their texts before pandas 3.1.
|
|
83
|
+
|
|
84
|
+
.. versionadded:: 0.1.0
|
|
85
|
+
|
|
86
|
+
Parameters
|
|
87
|
+
----------
|
|
88
|
+
texts
|
|
89
|
+
The texts holding the numbers, each one read by pandas without failure.
|
|
90
|
+
numbers
|
|
91
|
+
The numbers pandas read.
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
NDArray
|
|
96
|
+
The exact decimals, or the numbers themselves when pandas read them exactly or read integers.
|
|
97
|
+
|
|
98
|
+
Examples
|
|
99
|
+
--------
|
|
100
|
+
>>> import numpy
|
|
101
|
+
>>> from numdaplot.tables.frames.pandas_decimals import restore_exact_decimals
|
|
102
|
+
>>> texts = numpy.array(["0.5"], dtype=object)
|
|
103
|
+
>>> restore_exact_decimals(texts, numpy.array([0.5]))
|
|
104
|
+
array([0.5])
|
|
105
|
+
"""
|
|
106
|
+
if READS_EXACT_DECIMALS or numbers.dtype.kind != DECIMAL_KIND:
|
|
107
|
+
return numbers
|
|
108
|
+
|
|
109
|
+
text_list = cast(list[str], texts.tolist())
|
|
110
|
+
exact_list = [float(text) for text in text_list]
|
|
111
|
+
exact_numbers = numpy.array(exact_list, dtype=numbers.dtype)
|
|
112
|
+
|
|
113
|
+
return exact_numbers
|