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,143 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Checks of the column settings of a chart against the data it draws.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from numdaplot.arrays.array import Array
|
|
8
|
+
from numdaplot.errors.invalid_chart_data_error import InvalidChartDataError
|
|
9
|
+
from numdaplot.plots.data.array_values import read_array_values
|
|
10
|
+
from numdaplot.plots.data.chart_values import ChartValues
|
|
11
|
+
from numdaplot.plots.data.table_values import read_table_values
|
|
12
|
+
from numdaplot.tables.table import Table
|
|
13
|
+
|
|
14
|
+
TABLE_NAME = "a Table"
|
|
15
|
+
ARRAY_NAME = "an Array"
|
|
16
|
+
X_SETTING = "x"
|
|
17
|
+
Y_SETTING = "y"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def require_no_column_settings(chart_name: str, column_settings: dict[str, object]) -> None:
|
|
21
|
+
"""
|
|
22
|
+
Check that a chart drawing an Array names no column.
|
|
23
|
+
|
|
24
|
+
.. versionadded:: 0.1.0
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
chart_name
|
|
29
|
+
Name of the chart class, shown in the error message.
|
|
30
|
+
column_settings
|
|
31
|
+
Each column setting of the chart by name, such as ``{"x": None, "y": None}``.
|
|
32
|
+
|
|
33
|
+
Raises
|
|
34
|
+
------
|
|
35
|
+
InvalidChartDataError
|
|
36
|
+
At the first setting that is not None.
|
|
37
|
+
|
|
38
|
+
Examples
|
|
39
|
+
--------
|
|
40
|
+
>>> import numdaplot as ndp
|
|
41
|
+
>>> from numdaplot.plots.data.chart_data import require_no_column_settings
|
|
42
|
+
>>> try:
|
|
43
|
+
... require_no_column_settings("LineChart", {"x": "day", "y": None})
|
|
44
|
+
... except ndp.InvalidChartDataError as error:
|
|
45
|
+
... print(error)
|
|
46
|
+
LineChart takes no x for an Array.
|
|
47
|
+
"""
|
|
48
|
+
for setting_name, setting_value in column_settings.items():
|
|
49
|
+
if setting_value is not None:
|
|
50
|
+
raise InvalidChartDataError(chart_name, setting_name, ARRAY_NAME, False)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def require_column_setting[SettingValue](
|
|
54
|
+
chart_name: str, setting_name: str, setting_value: SettingValue | None
|
|
55
|
+
) -> SettingValue:
|
|
56
|
+
"""
|
|
57
|
+
Check that a chart drawing a Table has a column setting it needs, and return it.
|
|
58
|
+
|
|
59
|
+
.. versionadded:: 0.1.0
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
chart_name
|
|
64
|
+
Name of the chart class, shown in the error message.
|
|
65
|
+
setting_name
|
|
66
|
+
Name of the setting, such as ``y``.
|
|
67
|
+
setting_value
|
|
68
|
+
The value of the setting.
|
|
69
|
+
|
|
70
|
+
Returns
|
|
71
|
+
-------
|
|
72
|
+
SettingValue
|
|
73
|
+
The value, known not to be None.
|
|
74
|
+
|
|
75
|
+
Raises
|
|
76
|
+
------
|
|
77
|
+
InvalidChartDataError
|
|
78
|
+
When the value is None.
|
|
79
|
+
|
|
80
|
+
Examples
|
|
81
|
+
--------
|
|
82
|
+
>>> import numdaplot as ndp
|
|
83
|
+
>>> from numdaplot.plots.data.chart_data import require_column_setting
|
|
84
|
+
>>> try:
|
|
85
|
+
... require_column_setting("LineChart", "y", None)
|
|
86
|
+
... except ndp.InvalidChartDataError as error:
|
|
87
|
+
... print(error)
|
|
88
|
+
LineChart needs y for a Table.
|
|
89
|
+
"""
|
|
90
|
+
if setting_value is None:
|
|
91
|
+
raise InvalidChartDataError(chart_name, setting_name, TABLE_NAME, True)
|
|
92
|
+
|
|
93
|
+
return setting_value
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def read_chart_values(
|
|
97
|
+
data: Table | Array, x_name: str | None, y_names: list[str] | None, chart_name: str
|
|
98
|
+
) -> ChartValues:
|
|
99
|
+
"""
|
|
100
|
+
Return the positions and the series a line or bar chart draws from a Table or an Array.
|
|
101
|
+
|
|
102
|
+
.. versionadded:: 0.1.0
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
data
|
|
107
|
+
The Table or the Array drawn.
|
|
108
|
+
x_name
|
|
109
|
+
The ``x`` column of a Table, None for its row numbers and for an Array.
|
|
110
|
+
y_names
|
|
111
|
+
The ``y`` columns of a Table, None for an Array.
|
|
112
|
+
chart_name
|
|
113
|
+
Name of the chart class, shown in error messages.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
ChartValues
|
|
118
|
+
The values read by ``read_table_values`` or ``read_array_values``.
|
|
119
|
+
|
|
120
|
+
Raises
|
|
121
|
+
------
|
|
122
|
+
InvalidChartDataError
|
|
123
|
+
When a Table has no ``y`` columns, or an Array has ``x`` or ``y`` columns.
|
|
124
|
+
|
|
125
|
+
Examples
|
|
126
|
+
--------
|
|
127
|
+
>>> import numdaplot as ndp
|
|
128
|
+
>>> from numdaplot.plots.data.chart_data import read_chart_values
|
|
129
|
+
>>> prices = ndp.Array.from_list([12.0, 15.5])
|
|
130
|
+
>>> sales = ndp.Table.from_arrays({"price": prices})
|
|
131
|
+
>>> read_chart_values(sales, None, ["price"], "LineChart").value_name
|
|
132
|
+
'price'
|
|
133
|
+
"""
|
|
134
|
+
if isinstance(data, Array):
|
|
135
|
+
column_settings = dict[str, object]({X_SETTING: x_name, Y_SETTING: y_names})
|
|
136
|
+
require_no_column_settings(chart_name, column_settings)
|
|
137
|
+
array_values = read_array_values(data, chart_name)
|
|
138
|
+
return array_values
|
|
139
|
+
|
|
140
|
+
required_y_names = require_column_setting(chart_name, Y_SETTING, y_names)
|
|
141
|
+
table_values = read_table_values(data, x_name, required_y_names, chart_name)
|
|
142
|
+
|
|
143
|
+
return table_values
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Values a chart draws, read from a Table or an Array.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
import numpy
|
|
11
|
+
from numpy.typing import NDArray
|
|
12
|
+
|
|
13
|
+
from numdaplot.data_types.type import Type
|
|
14
|
+
from numdaplot.plots.data.position_kind import PositionKind
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True, eq=False)
|
|
18
|
+
class Positions:
|
|
19
|
+
"""
|
|
20
|
+
The ``x`` values of a chart.
|
|
21
|
+
|
|
22
|
+
.. versionadded:: 0.1.0
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
kind
|
|
27
|
+
Numbers, moments, texts or times of day.
|
|
28
|
+
values
|
|
29
|
+
One value per row: float64 numbers with NaN, datetime64[ns] clock times with NaT, texts, or float64 hours
|
|
30
|
+
since midnight with NaN.
|
|
31
|
+
name
|
|
32
|
+
The name of the ``x`` column, or None for row numbers.
|
|
33
|
+
|
|
34
|
+
Examples
|
|
35
|
+
--------
|
|
36
|
+
>>> import numpy
|
|
37
|
+
>>> from numdaplot.plots.data.chart_values import Positions
|
|
38
|
+
>>> from numdaplot.plots.data.position_kind import PositionKind
|
|
39
|
+
>>> Positions(PositionKind.NUMBERS, numpy.array([0.0, 1.0]), None).values
|
|
40
|
+
array([0., 1.])
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
kind: PositionKind
|
|
44
|
+
values: NDArray[Any]
|
|
45
|
+
name: str | None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True, eq=False)
|
|
49
|
+
class Series:
|
|
50
|
+
"""
|
|
51
|
+
One series of values drawn by a chart, as numbers.
|
|
52
|
+
|
|
53
|
+
.. versionadded:: 0.1.0
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
name
|
|
58
|
+
The name shown in the legend: the column name, or the column number of an Array.
|
|
59
|
+
values
|
|
60
|
+
One float64 number per row, NaN where the value is missing or not drawn. A time of day is its hours since
|
|
61
|
+
midnight, such as 15.5 for 15:30.
|
|
62
|
+
|
|
63
|
+
Examples
|
|
64
|
+
--------
|
|
65
|
+
>>> import numpy
|
|
66
|
+
>>> from numdaplot.plots.data.chart_values import Series
|
|
67
|
+
>>> Series("price", numpy.array([12.0, numpy.nan])).name
|
|
68
|
+
'price'
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
name: str
|
|
72
|
+
values: NDArray[numpy.float64]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@dataclass(frozen=True, eq=False)
|
|
76
|
+
class ChartValues:
|
|
77
|
+
"""
|
|
78
|
+
The positions and the series a chart draws.
|
|
79
|
+
|
|
80
|
+
.. versionadded:: 0.1.0
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
positions
|
|
85
|
+
The ``x`` values.
|
|
86
|
+
series
|
|
87
|
+
The series of numbers, each with one value per position.
|
|
88
|
+
rows
|
|
89
|
+
The row numbers of the source kept for drawing, to read other columns of the same rows.
|
|
90
|
+
value_name
|
|
91
|
+
The default label of the axis of the series: the name of the single ``y`` column of a Table, None
|
|
92
|
+
otherwise.
|
|
93
|
+
value_type
|
|
94
|
+
The type of the first series, of the family of every series: numbers or times of day.
|
|
95
|
+
|
|
96
|
+
Examples
|
|
97
|
+
--------
|
|
98
|
+
>>> import numdaplot as ndp
|
|
99
|
+
>>> from numdaplot.plots.data.array_values import read_array_values
|
|
100
|
+
>>> grid = ndp.Array.from_list([[1.0, 2.0], [3.0, 4.0]])
|
|
101
|
+
>>> [series.name for series in read_array_values(grid, "LineChart").series]
|
|
102
|
+
['0', '1']
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
positions: Positions
|
|
106
|
+
series: list[Series]
|
|
107
|
+
rows: NDArray[numpy.intp]
|
|
108
|
+
value_name: str | None
|
|
109
|
+
value_type: Type
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Reading of the Table columns a chart draws.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
import numpy
|
|
10
|
+
from numpy.typing import NDArray
|
|
11
|
+
|
|
12
|
+
from numdaplot.data_types.time_of_day import read_times
|
|
13
|
+
from numdaplot.data_types.type import Type
|
|
14
|
+
from numdaplot.data_types.value_family import ValueFamily, find_family
|
|
15
|
+
from numdaplot.errors.incompatible_types_error import IncompatibleTypesError
|
|
16
|
+
from numdaplot.plots.charts.box_chart import BoxChart
|
|
17
|
+
from numdaplot.plots.charts.histogram_chart import HistogramChart
|
|
18
|
+
from numdaplot.plots.charts.line_chart import LineChart
|
|
19
|
+
from numdaplot.plots.charts.scatter_chart import ScatterChart
|
|
20
|
+
from numdaplot.plots.data.position_kind import PositionKind
|
|
21
|
+
from numdaplot.tables.frames.column import Column
|
|
22
|
+
from numdaplot.tables.frames.column_values import find_column_missing, find_column_type
|
|
23
|
+
from numdaplot.tables.frames.named_column_errors import NamedColumnErrors
|
|
24
|
+
from numdaplot.tables.frames.time_zones import find_column_time_zone
|
|
25
|
+
|
|
26
|
+
POSITION_KINDS = {
|
|
27
|
+
ValueFamily.NUMBER: PositionKind.NUMBERS,
|
|
28
|
+
ValueFamily.MOMENT: PositionKind.MOMENTS,
|
|
29
|
+
ValueFamily.TEXT: PositionKind.TEXTS,
|
|
30
|
+
ValueFamily.BOOL: PositionKind.TEXTS,
|
|
31
|
+
ValueFamily.TIME: PositionKind.TIMES,
|
|
32
|
+
}
|
|
33
|
+
NUMBER_FAMILIES = frozenset({ValueFamily.NUMBER})
|
|
34
|
+
VALUE_FAMILIES = frozenset({ValueFamily.NUMBER, ValueFamily.TIME})
|
|
35
|
+
TIME_VALUE_CHARTS = frozenset({LineChart.__name__, ScatterChart.__name__, HistogramChart.__name__, BoxChart.__name__})
|
|
36
|
+
LABEL_FAMILIES = frozenset({ValueFamily.TEXT, ValueFamily.BOOL, ValueFamily.TIME})
|
|
37
|
+
HOUR_LABEL_PATTERN = "%H:%M"
|
|
38
|
+
MICROSECONDS_PER_HOUR = 3_600_000_000
|
|
39
|
+
TIME_DTYPE = numpy.dtype("timedelta64[us]")
|
|
40
|
+
MOMENT_DTYPE = numpy.dtype("datetime64[ns]")
|
|
41
|
+
TEXT_DTYPE = "string"
|
|
42
|
+
PYTHON_OBJECT_DTYPE = numpy.dtype(object)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def require_column_family(column: Column, accepted_families: frozenset[ValueFamily], chart_name: str) -> ValueFamily:
|
|
46
|
+
"""
|
|
47
|
+
Check that a column holds values a chart draws, and return their family.
|
|
48
|
+
|
|
49
|
+
.. versionadded:: 0.1.0
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
column
|
|
54
|
+
A Table column.
|
|
55
|
+
accepted_families
|
|
56
|
+
The families the chart draws in this column.
|
|
57
|
+
chart_name
|
|
58
|
+
Name of the chart class, shown in the error message.
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
ValueFamily
|
|
63
|
+
The family of the column.
|
|
64
|
+
|
|
65
|
+
Raises
|
|
66
|
+
------
|
|
67
|
+
IncompatibleTypesError
|
|
68
|
+
When the column holds values of another family, such as durations.
|
|
69
|
+
|
|
70
|
+
Examples
|
|
71
|
+
--------
|
|
72
|
+
>>> import pandas
|
|
73
|
+
>>> import numdaplot as ndp
|
|
74
|
+
>>> from numdaplot.plots.data.column_reading import NUMBER_FAMILIES, require_column_family
|
|
75
|
+
>>> try:
|
|
76
|
+
... require_column_family(pandas.Series([True], dtype="boolean"), NUMBER_FAMILIES, "LineChart")
|
|
77
|
+
... except ndp.IncompatibleTypesError as error:
|
|
78
|
+
... print(error)
|
|
79
|
+
Cannot apply LineChart to BOOL.
|
|
80
|
+
"""
|
|
81
|
+
column_type = find_column_type(column)
|
|
82
|
+
family = find_family(column_type)
|
|
83
|
+
if family not in accepted_families:
|
|
84
|
+
with NamedColumnErrors(column):
|
|
85
|
+
raise IncompatibleTypesError(chart_name, [column_type.name])
|
|
86
|
+
|
|
87
|
+
return family
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def read_numbers(column: Column, chart_name: str) -> NDArray[numpy.float64]:
|
|
91
|
+
"""
|
|
92
|
+
Return a column of numbers as float64 values, NaN where a value is missing.
|
|
93
|
+
|
|
94
|
+
.. versionadded:: 0.1.0
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
column
|
|
99
|
+
A Table column.
|
|
100
|
+
chart_name
|
|
101
|
+
Name of the chart class, shown in the error message.
|
|
102
|
+
|
|
103
|
+
Returns
|
|
104
|
+
-------
|
|
105
|
+
NDArray[numpy.float64]
|
|
106
|
+
One number per row.
|
|
107
|
+
|
|
108
|
+
Raises
|
|
109
|
+
------
|
|
110
|
+
IncompatibleTypesError
|
|
111
|
+
When the column does not hold numbers.
|
|
112
|
+
|
|
113
|
+
Examples
|
|
114
|
+
--------
|
|
115
|
+
>>> import pandas
|
|
116
|
+
>>> from numdaplot.plots.data.column_reading import read_numbers
|
|
117
|
+
>>> read_numbers(pandas.Series([3, None], dtype="Int64"), "LineChart")
|
|
118
|
+
array([ 3., nan])
|
|
119
|
+
"""
|
|
120
|
+
require_column_family(column, NUMBER_FAMILIES, chart_name)
|
|
121
|
+
numbers = column.to_numpy(dtype=numpy.float64, na_value=numpy.nan)
|
|
122
|
+
|
|
123
|
+
return numbers
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def find_value_families(chart_name: str) -> frozenset[ValueFamily]:
|
|
127
|
+
"""
|
|
128
|
+
Return the families of the values a chart draws: numbers, and times of day for the charts measuring them.
|
|
129
|
+
|
|
130
|
+
.. versionadded:: 0.1.0
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
chart_name
|
|
135
|
+
Name of the chart class.
|
|
136
|
+
|
|
137
|
+
Returns
|
|
138
|
+
-------
|
|
139
|
+
frozenset[ValueFamily]
|
|
140
|
+
Numbers and times of day for a LineChart, a ScatterChart, a HistogramChart or a BoxChart, numbers only
|
|
141
|
+
otherwise.
|
|
142
|
+
|
|
143
|
+
Examples
|
|
144
|
+
--------
|
|
145
|
+
>>> from numdaplot.plots.data.column_reading import find_value_families
|
|
146
|
+
>>> sorted(family.name for family in find_value_families("BoxChart"))
|
|
147
|
+
['NUMBER', 'TIME']
|
|
148
|
+
>>> sorted(family.name for family in find_value_families("BarChart"))
|
|
149
|
+
['NUMBER']
|
|
150
|
+
"""
|
|
151
|
+
if chart_name in TIME_VALUE_CHARTS:
|
|
152
|
+
return VALUE_FAMILIES
|
|
153
|
+
|
|
154
|
+
return NUMBER_FAMILIES
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def read_values(column: Column, chart_name: str) -> NDArray[numpy.float64]:
|
|
158
|
+
"""
|
|
159
|
+
Return a column of values a chart draws as float64 numbers, a time of day being its hours since midnight.
|
|
160
|
+
|
|
161
|
+
.. versionadded:: 0.1.0
|
|
162
|
+
|
|
163
|
+
Parameters
|
|
164
|
+
----------
|
|
165
|
+
column
|
|
166
|
+
A Table column.
|
|
167
|
+
chart_name
|
|
168
|
+
Name of the chart class, shown in the error message.
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
NDArray[numpy.float64]
|
|
173
|
+
One number per row, NaN where a value is missing.
|
|
174
|
+
|
|
175
|
+
Raises
|
|
176
|
+
------
|
|
177
|
+
IncompatibleTypesError
|
|
178
|
+
When the column does not hold numbers, or times of day for a chart measuring them.
|
|
179
|
+
|
|
180
|
+
Examples
|
|
181
|
+
--------
|
|
182
|
+
>>> import numpy
|
|
183
|
+
>>> import pandas
|
|
184
|
+
>>> from numdaplot.plots.data.column_reading import read_values
|
|
185
|
+
>>> read_values(pandas.Series(numpy.array([55800000000], dtype="timedelta64[us]")), "BoxChart")
|
|
186
|
+
array([15.5])
|
|
187
|
+
"""
|
|
188
|
+
value_families = find_value_families(chart_name)
|
|
189
|
+
family = require_column_family(column, value_families, chart_name)
|
|
190
|
+
if family == ValueFamily.TIME:
|
|
191
|
+
hours = read_hours(column)
|
|
192
|
+
return hours
|
|
193
|
+
|
|
194
|
+
numbers = read_numbers(column, chart_name)
|
|
195
|
+
|
|
196
|
+
return numbers
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def require_same_family(column: Column, value_type: Type, chart_name: str) -> None:
|
|
200
|
+
"""
|
|
201
|
+
Check that a column holds values of the family of the first column a chart draws on the same axis.
|
|
202
|
+
|
|
203
|
+
.. versionadded:: 0.1.0
|
|
204
|
+
|
|
205
|
+
Parameters
|
|
206
|
+
----------
|
|
207
|
+
column
|
|
208
|
+
A Table column.
|
|
209
|
+
value_type
|
|
210
|
+
The type of the first column.
|
|
211
|
+
chart_name
|
|
212
|
+
Name of the chart class, shown in the error message.
|
|
213
|
+
|
|
214
|
+
Raises
|
|
215
|
+
------
|
|
216
|
+
IncompatibleTypesError
|
|
217
|
+
When one holds numbers and the other times of day.
|
|
218
|
+
|
|
219
|
+
Examples
|
|
220
|
+
--------
|
|
221
|
+
>>> import numpy
|
|
222
|
+
>>> import pandas
|
|
223
|
+
>>> import numdaplot as ndp
|
|
224
|
+
>>> from numdaplot.plots.data.column_reading import require_same_family
|
|
225
|
+
>>> counts = pandas.Series([3.0], name="count")
|
|
226
|
+
>>> try:
|
|
227
|
+
... require_same_family(counts, ndp.Type.TIME, "BoxChart")
|
|
228
|
+
... except ndp.IncompatibleTypesError as error:
|
|
229
|
+
... print(error)
|
|
230
|
+
Cannot apply BoxChart to the FLOAT64 column 'count' and TIME.
|
|
231
|
+
"""
|
|
232
|
+
column_type = find_column_type(column)
|
|
233
|
+
column_family = find_family(column_type)
|
|
234
|
+
value_family = find_family(value_type)
|
|
235
|
+
if column_family != value_family:
|
|
236
|
+
with NamedColumnErrors(column):
|
|
237
|
+
raise IncompatibleTypesError(chart_name, [column_type.name, value_type.name])
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def read_texts(column: Column, chart_name: str) -> NDArray[Any]:
|
|
241
|
+
"""
|
|
242
|
+
Return a column of texts, categories, booleans or times of day as Python texts, None where a value is missing.
|
|
243
|
+
|
|
244
|
+
A time of day is written ``HH:MM``.
|
|
245
|
+
|
|
246
|
+
.. versionadded:: 0.1.0
|
|
247
|
+
|
|
248
|
+
Parameters
|
|
249
|
+
----------
|
|
250
|
+
column
|
|
251
|
+
A Table column.
|
|
252
|
+
chart_name
|
|
253
|
+
Name of the chart class, shown in the error message.
|
|
254
|
+
|
|
255
|
+
Returns
|
|
256
|
+
-------
|
|
257
|
+
NDArray
|
|
258
|
+
One text per row, in a numpy array of Python objects.
|
|
259
|
+
|
|
260
|
+
Raises
|
|
261
|
+
------
|
|
262
|
+
IncompatibleTypesError
|
|
263
|
+
When the column does not hold texts.
|
|
264
|
+
|
|
265
|
+
Examples
|
|
266
|
+
--------
|
|
267
|
+
>>> import pandas
|
|
268
|
+
>>> from numdaplot.plots.data.column_reading import read_texts
|
|
269
|
+
>>> read_texts(pandas.Series(["Paris", None], dtype="string"), "BarChart")
|
|
270
|
+
array(['Paris', None], dtype=object)
|
|
271
|
+
"""
|
|
272
|
+
family = require_column_family(column, LABEL_FAMILIES, chart_name)
|
|
273
|
+
if family == ValueFamily.TIME:
|
|
274
|
+
hour_texts = write_hour_labels(column)
|
|
275
|
+
return hour_texts
|
|
276
|
+
|
|
277
|
+
text_column = column.astype(TEXT_DTYPE)
|
|
278
|
+
text_values = text_column.tolist()
|
|
279
|
+
missing = find_column_missing(column)
|
|
280
|
+
value_pairs = zip(text_values, missing, strict=True)
|
|
281
|
+
present_texts = [None if is_missing else text for text, is_missing in value_pairs]
|
|
282
|
+
texts = numpy.array(present_texts, dtype=PYTHON_OBJECT_DTYPE)
|
|
283
|
+
|
|
284
|
+
return texts
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def read_moments(column: Column) -> NDArray[numpy.datetime64]:
|
|
288
|
+
"""
|
|
289
|
+
Return a column of dates or datetimes as the clock times shown in its time zone, NaT where a value is missing.
|
|
290
|
+
|
|
291
|
+
.. versionadded:: 0.1.0
|
|
292
|
+
|
|
293
|
+
Parameters
|
|
294
|
+
----------
|
|
295
|
+
column
|
|
296
|
+
A date or datetime column.
|
|
297
|
+
|
|
298
|
+
Returns
|
|
299
|
+
-------
|
|
300
|
+
NDArray[numpy.datetime64]
|
|
301
|
+
One datetime64[ns] value per row, without time zone.
|
|
302
|
+
|
|
303
|
+
Examples
|
|
304
|
+
--------
|
|
305
|
+
>>> import pandas
|
|
306
|
+
>>> from numdaplot.plots.data.column_reading import read_moments
|
|
307
|
+
>>> utc_times = pandas.Series(pandas.to_datetime(["2026-07-01 10:30"])).dt.tz_localize("UTC")
|
|
308
|
+
>>> read_moments(utc_times.dt.tz_convert("Europe/Paris"))
|
|
309
|
+
array(['2026-07-01T12:30:00.000000000'], dtype='datetime64[ns]')
|
|
310
|
+
"""
|
|
311
|
+
clock_times = column
|
|
312
|
+
time_zone = find_column_time_zone(column)
|
|
313
|
+
if time_zone is not None:
|
|
314
|
+
clock_times = column.dt.tz_localize(None)
|
|
315
|
+
|
|
316
|
+
moments = clock_times.to_numpy(dtype=MOMENT_DTYPE)
|
|
317
|
+
|
|
318
|
+
return moments
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def read_positions(column: Column, chart_name: str) -> tuple[PositionKind, NDArray[Any]]:
|
|
322
|
+
"""
|
|
323
|
+
Return the ``x`` values of a chart read from a column, with their kind.
|
|
324
|
+
|
|
325
|
+
.. versionadded:: 0.1.0
|
|
326
|
+
|
|
327
|
+
Parameters
|
|
328
|
+
----------
|
|
329
|
+
column
|
|
330
|
+
A Table column of numbers, dates, datetimes or texts.
|
|
331
|
+
chart_name
|
|
332
|
+
Name of the chart class, shown in the error message.
|
|
333
|
+
|
|
334
|
+
Returns
|
|
335
|
+
-------
|
|
336
|
+
tuple[PositionKind, NDArray]
|
|
337
|
+
The kind and the values, read by ``read_numbers``, ``read_moments`` or ``read_texts``.
|
|
338
|
+
|
|
339
|
+
Raises
|
|
340
|
+
------
|
|
341
|
+
IncompatibleTypesError
|
|
342
|
+
When the column holds durations.
|
|
343
|
+
|
|
344
|
+
Examples
|
|
345
|
+
--------
|
|
346
|
+
>>> import pandas
|
|
347
|
+
>>> from numdaplot.plots.data.column_reading import read_positions
|
|
348
|
+
>>> read_positions(pandas.Series(["Paris"], dtype="string"), "BarChart")
|
|
349
|
+
(<PositionKind.TEXTS: 3>, array(['Paris'], dtype=object))
|
|
350
|
+
"""
|
|
351
|
+
accepted_families = frozenset(POSITION_KINDS)
|
|
352
|
+
family = require_column_family(column, accepted_families, chart_name)
|
|
353
|
+
kind = POSITION_KINDS[family]
|
|
354
|
+
if kind == PositionKind.NUMBERS:
|
|
355
|
+
numbers = read_numbers(column, chart_name)
|
|
356
|
+
return kind, numbers
|
|
357
|
+
|
|
358
|
+
if kind == PositionKind.MOMENTS:
|
|
359
|
+
moments = read_moments(column)
|
|
360
|
+
return kind, moments
|
|
361
|
+
|
|
362
|
+
if kind == PositionKind.TIMES:
|
|
363
|
+
hours = read_hours(column)
|
|
364
|
+
return kind, hours
|
|
365
|
+
|
|
366
|
+
texts = read_texts(column, chart_name)
|
|
367
|
+
|
|
368
|
+
return kind, texts
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def read_hours(column: Column) -> NDArray[numpy.float64]:
|
|
372
|
+
"""
|
|
373
|
+
Return a column of times of day as the hours since midnight, NaN where a time is missing.
|
|
374
|
+
|
|
375
|
+
.. versionadded:: 0.1.0
|
|
376
|
+
|
|
377
|
+
Parameters
|
|
378
|
+
----------
|
|
379
|
+
column
|
|
380
|
+
A Table column of times of day.
|
|
381
|
+
|
|
382
|
+
Returns
|
|
383
|
+
-------
|
|
384
|
+
NDArray[numpy.float64]
|
|
385
|
+
The hours, such as 15.5 for 15:30.
|
|
386
|
+
|
|
387
|
+
Examples
|
|
388
|
+
--------
|
|
389
|
+
>>> import numpy
|
|
390
|
+
>>> import pandas
|
|
391
|
+
>>> from numdaplot.plots.data.column_reading import read_hours
|
|
392
|
+
>>> read_hours(pandas.Series(numpy.array([55800000000, "NaT"], dtype="timedelta64[us]")))
|
|
393
|
+
array([15.5, nan])
|
|
394
|
+
"""
|
|
395
|
+
stored_times = column.to_numpy(dtype=TIME_DTYPE)
|
|
396
|
+
hours = count_hours(stored_times)
|
|
397
|
+
|
|
398
|
+
return hours
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
def count_hours(stored_times: NDArray[numpy.timedelta64]) -> NDArray[numpy.float64]:
|
|
402
|
+
"""
|
|
403
|
+
Return stored times of day as the hours since midnight, NaN where a time is missing.
|
|
404
|
+
|
|
405
|
+
.. versionadded:: 0.1.0
|
|
406
|
+
|
|
407
|
+
Parameters
|
|
408
|
+
----------
|
|
409
|
+
stored_times
|
|
410
|
+
Times of day as ``timedelta64[us]`` values since midnight, of any shape.
|
|
411
|
+
|
|
412
|
+
Returns
|
|
413
|
+
-------
|
|
414
|
+
NDArray[numpy.float64]
|
|
415
|
+
The hours, of the same shape, such as 15.5 for 15:30.
|
|
416
|
+
|
|
417
|
+
Examples
|
|
418
|
+
--------
|
|
419
|
+
>>> import numpy
|
|
420
|
+
>>> from numdaplot.plots.data.column_reading import count_hours
|
|
421
|
+
>>> count_hours(numpy.array([[55800000000, "NaT"]], dtype="timedelta64[us]"))
|
|
422
|
+
array([[15.5, nan]])
|
|
423
|
+
"""
|
|
424
|
+
missing = numpy.isnat(stored_times)
|
|
425
|
+
microseconds = stored_times.astype(numpy.float64)
|
|
426
|
+
hours = microseconds / MICROSECONDS_PER_HOUR
|
|
427
|
+
present_hours = numpy.where(missing, numpy.nan, hours)
|
|
428
|
+
|
|
429
|
+
return present_hours
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
def write_hour_labels(column: Column) -> NDArray[Any]:
|
|
433
|
+
"""
|
|
434
|
+
Return a column of times of day as ``HH:MM`` texts, None where a time is missing.
|
|
435
|
+
|
|
436
|
+
.. versionadded:: 0.1.0
|
|
437
|
+
|
|
438
|
+
Parameters
|
|
439
|
+
----------
|
|
440
|
+
column
|
|
441
|
+
A Table column of times of day.
|
|
442
|
+
|
|
443
|
+
Returns
|
|
444
|
+
-------
|
|
445
|
+
NDArray
|
|
446
|
+
One text per row, in a numpy array of Python objects.
|
|
447
|
+
|
|
448
|
+
Examples
|
|
449
|
+
--------
|
|
450
|
+
>>> import numpy
|
|
451
|
+
>>> import pandas
|
|
452
|
+
>>> from numdaplot.plots.data.column_reading import write_hour_labels
|
|
453
|
+
>>> write_hour_labels(pandas.Series(numpy.array([55800000000, "NaT"], dtype="timedelta64[us]")))
|
|
454
|
+
array(['15:30', None], dtype=object)
|
|
455
|
+
"""
|
|
456
|
+
stored_times = column.to_numpy(dtype=TIME_DTYPE)
|
|
457
|
+
times = read_times(stored_times)
|
|
458
|
+
hour_labels = list[str | None]()
|
|
459
|
+
for time_of_day in times:
|
|
460
|
+
hour_label = None
|
|
461
|
+
if time_of_day is not None:
|
|
462
|
+
hour_label = time_of_day.strftime(HOUR_LABEL_PATTERN)
|
|
463
|
+
|
|
464
|
+
hour_labels.append(hour_label)
|
|
465
|
+
|
|
466
|
+
label_values = numpy.array(hour_labels, dtype=PYTHON_OBJECT_DTYPE)
|
|
467
|
+
|
|
468
|
+
return label_values
|