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,419 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Application of a time function to each value of an Array.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Literal, cast
|
|
8
|
+
|
|
9
|
+
import numpy
|
|
10
|
+
import pandas
|
|
11
|
+
from numpy.typing import NDArray
|
|
12
|
+
|
|
13
|
+
from numdaplot.arrays.operations.time_bounds import require_decimal_durations_fit, require_whole_durations_fit
|
|
14
|
+
from numdaplot.arrays.operations.type_requirements import require_family
|
|
15
|
+
from numdaplot.data_types.numpy_mapping import from_numpy_dtype, to_numpy_dtype
|
|
16
|
+
from numdaplot.data_types.type import Type
|
|
17
|
+
from numdaplot.data_types.value_family import ValueFamily
|
|
18
|
+
from numdaplot.dates.date_part import DatePart
|
|
19
|
+
from numdaplot.dates.date_part_unit import DatePartUnit
|
|
20
|
+
from numdaplot.dates.date_period import DatePeriod
|
|
21
|
+
from numdaplot.dates.duration_in import DurationIn
|
|
22
|
+
from numdaplot.dates.duration_unit import DurationUnit
|
|
23
|
+
from numdaplot.dates.period_unit import PeriodUnit
|
|
24
|
+
from numdaplot.dates.time_function import TimeFunction
|
|
25
|
+
from numdaplot.dates.to_duration import ToDuration
|
|
26
|
+
from numdaplot.errors.incompatible_types_error import IncompatibleTypesError
|
|
27
|
+
from numdaplot.errors.refused_operation_error import RefusedOperationError
|
|
28
|
+
|
|
29
|
+
MOMENT_FAMILIES = frozenset({ValueFamily.MOMENT})
|
|
30
|
+
DURATION_FAMILIES = frozenset({ValueFamily.DURATION})
|
|
31
|
+
NUMBER_FAMILIES = frozenset({ValueFamily.NUMBER})
|
|
32
|
+
TIME_OF_DAY_PARTS = frozenset({DatePartUnit.HOUR, DatePartUnit.MINUTE, DatePartUnit.SECOND})
|
|
33
|
+
# The microseconds in one unit of each part of a time of day, and the number of such units in the next larger part.
|
|
34
|
+
TIME_PART_SIZES = {
|
|
35
|
+
DatePartUnit.HOUR: (3_600_000_000, 24),
|
|
36
|
+
DatePartUnit.MINUTE: (60_000_000, 60),
|
|
37
|
+
DatePartUnit.SECOND: (1_000_000, 60),
|
|
38
|
+
}
|
|
39
|
+
WHOLE_DTYPE = numpy.int64
|
|
40
|
+
PART_ATTRIBUTES = {
|
|
41
|
+
DatePartUnit.YEAR: "year",
|
|
42
|
+
DatePartUnit.QUARTER: "quarter",
|
|
43
|
+
DatePartUnit.MONTH: "month",
|
|
44
|
+
DatePartUnit.DAY: "day",
|
|
45
|
+
DatePartUnit.DAY_OF_YEAR: "day_of_year",
|
|
46
|
+
DatePartUnit.HOUR: "hour",
|
|
47
|
+
DatePartUnit.MINUTE: "minute",
|
|
48
|
+
DatePartUnit.SECOND: "second",
|
|
49
|
+
}
|
|
50
|
+
ISO_WEEK_COLUMN = "week"
|
|
51
|
+
# pandas numbers the days of the week from 0 for Monday, numdaplot from 1 for Monday.
|
|
52
|
+
WEEKDAY_SHIFT = 1
|
|
53
|
+
PERIOD_FREQUENCIES = {
|
|
54
|
+
PeriodUnit.YEAR: "Y",
|
|
55
|
+
PeriodUnit.QUARTER: "Q",
|
|
56
|
+
PeriodUnit.MONTH: "M",
|
|
57
|
+
# Weeks ending on Sunday, so each period starts on Monday.
|
|
58
|
+
PeriodUnit.WEEK: "W-SUN",
|
|
59
|
+
PeriodUnit.DAY: "D",
|
|
60
|
+
PeriodUnit.HOUR: "h",
|
|
61
|
+
}
|
|
62
|
+
type DurationCode = Literal["W", "D", "h", "m", "s"]
|
|
63
|
+
DURATION_UNIT_CODES = dict[DurationUnit, DurationCode](
|
|
64
|
+
{
|
|
65
|
+
DurationUnit.WEEK: "W",
|
|
66
|
+
DurationUnit.DAY: "D",
|
|
67
|
+
DurationUnit.HOUR: "h",
|
|
68
|
+
DurationUnit.MINUTE: "m",
|
|
69
|
+
DurationUnit.SECOND: "s",
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
NANOSECOND_CODE = "ns"
|
|
73
|
+
WHOLE_NUMBER_KINDS = frozenset({"i", "u"})
|
|
74
|
+
NOT_A_TIME = "NaT"
|
|
75
|
+
UNKNOWN_FUNCTION_OPERATION = "The time function {function_name}"
|
|
76
|
+
UNKNOWN_FUNCTION_ALTERNATIVE = "a time function of numdaplot"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def apply_time_function(values: NDArray[Any], function: TimeFunction) -> NDArray[Any]:
|
|
80
|
+
"""
|
|
81
|
+
Return the result of a time function applied to each value.
|
|
82
|
+
|
|
83
|
+
.. versionadded:: 0.1.0
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
values
|
|
88
|
+
The values of an Array.
|
|
89
|
+
function
|
|
90
|
+
Any time function of numdaplot.
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
NDArray
|
|
95
|
+
The results, of the same shape. Missing values stay missing.
|
|
96
|
+
|
|
97
|
+
Raises
|
|
98
|
+
------
|
|
99
|
+
IncompatibleTypesError
|
|
100
|
+
When the function does not apply to the type of the values, such as an hour read from dates.
|
|
101
|
+
RefusedOperationError
|
|
102
|
+
When the function is not a time function of numdaplot.
|
|
103
|
+
|
|
104
|
+
Examples
|
|
105
|
+
--------
|
|
106
|
+
>>> import numpy
|
|
107
|
+
>>> import numdaplot as ndp
|
|
108
|
+
>>> from numdaplot.arrays.calculation.time_function_values import apply_time_function
|
|
109
|
+
>>> days = numpy.array(["2026-12-31"], dtype="datetime64[D]")
|
|
110
|
+
>>> apply_time_function(days, ndp.DatePart(unit=ndp.DatePartUnit.MONTH))
|
|
111
|
+
array([12.])
|
|
112
|
+
"""
|
|
113
|
+
function_class = type(function)
|
|
114
|
+
function_name = function_class.__name__
|
|
115
|
+
|
|
116
|
+
match function:
|
|
117
|
+
case DatePart():
|
|
118
|
+
results = read_date_parts(values, function.unit, function_name)
|
|
119
|
+
case DatePeriod():
|
|
120
|
+
results = find_date_periods(values, function.unit, function_name)
|
|
121
|
+
case DurationIn():
|
|
122
|
+
results = count_durations(values, function.unit, function_name)
|
|
123
|
+
case ToDuration():
|
|
124
|
+
results = build_durations(values, function.unit, function_name)
|
|
125
|
+
case _:
|
|
126
|
+
operation = UNKNOWN_FUNCTION_OPERATION.format(function_name=function_name)
|
|
127
|
+
raise RefusedOperationError(operation, UNKNOWN_FUNCTION_ALTERNATIVE)
|
|
128
|
+
|
|
129
|
+
return results
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def require_moments(values: NDArray[Any], needs_time_of_day: bool, function_name: str) -> None:
|
|
133
|
+
"""
|
|
134
|
+
Check that values are dates or datetimes, and datetimes when a time of day is needed.
|
|
135
|
+
|
|
136
|
+
.. versionadded:: 0.1.0
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
values
|
|
141
|
+
The values of an Array.
|
|
142
|
+
needs_time_of_day
|
|
143
|
+
True when the function reads or keeps hours, which dates do not have.
|
|
144
|
+
function_name
|
|
145
|
+
Name of the function, shown in the error message.
|
|
146
|
+
|
|
147
|
+
Raises
|
|
148
|
+
------
|
|
149
|
+
IncompatibleTypesError
|
|
150
|
+
When the values are not dates or datetimes, or are dates and a time of day is needed.
|
|
151
|
+
|
|
152
|
+
Examples
|
|
153
|
+
--------
|
|
154
|
+
>>> import numpy
|
|
155
|
+
>>> import numdaplot as ndp
|
|
156
|
+
>>> from numdaplot.arrays.calculation.time_function_values import require_moments
|
|
157
|
+
>>> try:
|
|
158
|
+
... require_moments(numpy.array(["2026-12-31"], dtype="datetime64[D]"), True, "DatePart")
|
|
159
|
+
... except ndp.IncompatibleTypesError as error:
|
|
160
|
+
... print(error)
|
|
161
|
+
Cannot apply DatePart to DATE.
|
|
162
|
+
"""
|
|
163
|
+
require_family(values, MOMENT_FAMILIES, function_name)
|
|
164
|
+
values_type = from_numpy_dtype(values.dtype)
|
|
165
|
+
misses_time_of_day = needs_time_of_day and values_type == Type.DATE
|
|
166
|
+
if misses_time_of_day:
|
|
167
|
+
raise IncompatibleTypesError(function_name, [values_type.name])
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def read_date_parts(values: NDArray[Any], unit: DatePartUnit, function_name: str) -> NDArray[numpy.float64]:
|
|
171
|
+
"""
|
|
172
|
+
Return a part of each date or datetime, as a decimal number.
|
|
173
|
+
|
|
174
|
+
.. versionadded:: 0.1.0
|
|
175
|
+
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
values
|
|
179
|
+
The values of a date or datetime Array.
|
|
180
|
+
unit
|
|
181
|
+
The part to read.
|
|
182
|
+
function_name
|
|
183
|
+
Name of the function, shown in error messages.
|
|
184
|
+
|
|
185
|
+
Returns
|
|
186
|
+
-------
|
|
187
|
+
NDArray[numpy.float64]
|
|
188
|
+
The parts, NaN for a missing value.
|
|
189
|
+
|
|
190
|
+
Raises
|
|
191
|
+
------
|
|
192
|
+
IncompatibleTypesError
|
|
193
|
+
When the values are not dates or datetimes, or are dates and the part is a time of day.
|
|
194
|
+
|
|
195
|
+
Examples
|
|
196
|
+
--------
|
|
197
|
+
>>> import numpy
|
|
198
|
+
>>> import numdaplot as ndp
|
|
199
|
+
>>> from numdaplot.arrays.calculation.time_function_values import read_date_parts
|
|
200
|
+
>>> read_date_parts(numpy.array(["2026-12-31", "NaT"], dtype="datetime64[D]"), ndp.DatePartUnit.WEEK, "DatePart")
|
|
201
|
+
array([53., nan])
|
|
202
|
+
"""
|
|
203
|
+
needs_time_of_day = unit in TIME_OF_DAY_PARTS
|
|
204
|
+
values_type = from_numpy_dtype(values.dtype)
|
|
205
|
+
if values_type == Type.TIME and needs_time_of_day:
|
|
206
|
+
time_parts = read_time_parts(values, unit)
|
|
207
|
+
return time_parts
|
|
208
|
+
|
|
209
|
+
require_moments(values, needs_time_of_day, function_name)
|
|
210
|
+
flat_values = values.ravel()
|
|
211
|
+
moments = pandas.DatetimeIndex(flat_values)
|
|
212
|
+
if unit == DatePartUnit.WEEK:
|
|
213
|
+
iso_calendar = moments.isocalendar()
|
|
214
|
+
iso_weeks = iso_calendar[ISO_WEEK_COLUMN]
|
|
215
|
+
flat_parts = iso_weeks.to_numpy(dtype=numpy.float64, na_value=numpy.nan)
|
|
216
|
+
elif unit == DatePartUnit.WEEKDAY:
|
|
217
|
+
weekdays = numpy.asarray(moments.day_of_week, dtype=numpy.float64)
|
|
218
|
+
flat_parts = weekdays + WEEKDAY_SHIFT
|
|
219
|
+
else:
|
|
220
|
+
part_attribute = PART_ATTRIBUTES[unit]
|
|
221
|
+
parts = getattr(moments, part_attribute)
|
|
222
|
+
flat_parts = numpy.asarray(parts, dtype=numpy.float64)
|
|
223
|
+
|
|
224
|
+
shaped_parts = flat_parts.reshape(values.shape)
|
|
225
|
+
# Some versions of the numpy stubs widen the decimals of the reshaped parts.
|
|
226
|
+
date_parts = cast(NDArray[numpy.float64], shaped_parts)
|
|
227
|
+
|
|
228
|
+
return date_parts
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def read_time_parts(values: NDArray[Any], unit: DatePartUnit) -> NDArray[numpy.float64]:
|
|
232
|
+
"""
|
|
233
|
+
Return the hour, the minute or the second of times of day stored as the time since midnight.
|
|
234
|
+
|
|
235
|
+
.. versionadded:: 0.1.0
|
|
236
|
+
|
|
237
|
+
Parameters
|
|
238
|
+
----------
|
|
239
|
+
values
|
|
240
|
+
Times of day in ``timedelta64[us]``.
|
|
241
|
+
unit
|
|
242
|
+
``HOUR``, ``MINUTE`` or ``SECOND``.
|
|
243
|
+
|
|
244
|
+
Returns
|
|
245
|
+
-------
|
|
246
|
+
NDArray[numpy.float64]
|
|
247
|
+
The parts, in the shape of the values, NaN where a time is missing.
|
|
248
|
+
|
|
249
|
+
Examples
|
|
250
|
+
--------
|
|
251
|
+
>>> import numpy
|
|
252
|
+
>>> import numdaplot as ndp
|
|
253
|
+
>>> from numdaplot.arrays.calculation.time_function_values import read_time_parts
|
|
254
|
+
>>> times = numpy.array([56130000000, "NaT"], dtype="timedelta64[us]")
|
|
255
|
+
>>> read_time_parts(times, ndp.DatePartUnit.MINUTE)
|
|
256
|
+
array([35., nan])
|
|
257
|
+
"""
|
|
258
|
+
missing = numpy.isnat(values)
|
|
259
|
+
microseconds = values.astype(WHOLE_DTYPE)
|
|
260
|
+
unit_size, unit_count = TIME_PART_SIZES[unit]
|
|
261
|
+
whole_units = microseconds // unit_size
|
|
262
|
+
parts = whole_units % unit_count
|
|
263
|
+
decimal_parts = parts.astype(numpy.float64)
|
|
264
|
+
time_parts = numpy.where(missing, numpy.nan, decimal_parts)
|
|
265
|
+
|
|
266
|
+
return time_parts
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def find_date_periods(values: NDArray[Any], unit: PeriodUnit, function_name: str) -> NDArray[Any]:
|
|
270
|
+
"""
|
|
271
|
+
Return the first moment of the period holding each date or datetime.
|
|
272
|
+
|
|
273
|
+
.. versionadded:: 0.1.0
|
|
274
|
+
|
|
275
|
+
Parameters
|
|
276
|
+
----------
|
|
277
|
+
values
|
|
278
|
+
The values of a date or datetime Array.
|
|
279
|
+
unit
|
|
280
|
+
The length of the periods.
|
|
281
|
+
function_name
|
|
282
|
+
Name of the function, shown in error messages.
|
|
283
|
+
|
|
284
|
+
Returns
|
|
285
|
+
-------
|
|
286
|
+
NDArray
|
|
287
|
+
Dates, or datetimes for ``PeriodUnit.HOUR``, NaT for a missing value.
|
|
288
|
+
|
|
289
|
+
Raises
|
|
290
|
+
------
|
|
291
|
+
IncompatibleTypesError
|
|
292
|
+
When the values are not dates or datetimes, or are dates and the unit is the hour.
|
|
293
|
+
|
|
294
|
+
Examples
|
|
295
|
+
--------
|
|
296
|
+
>>> import numpy
|
|
297
|
+
>>> import numdaplot as ndp
|
|
298
|
+
>>> from numdaplot.arrays.calculation.time_function_values import find_date_periods
|
|
299
|
+
>>> find_date_periods(numpy.array(["2026-12-31"], dtype="datetime64[D]"), ndp.PeriodUnit.WEEK, "DatePeriod")
|
|
300
|
+
array(['2026-12-28'], dtype='datetime64[D]')
|
|
301
|
+
"""
|
|
302
|
+
needs_time_of_day = unit == PeriodUnit.HOUR
|
|
303
|
+
require_moments(values, needs_time_of_day, function_name)
|
|
304
|
+
flat_values = values.ravel()
|
|
305
|
+
moments = pandas.DatetimeIndex(flat_values)
|
|
306
|
+
frequency = PERIOD_FREQUENCIES[unit]
|
|
307
|
+
periods = moments.to_period(frequency)
|
|
308
|
+
period_starts = periods.start_time
|
|
309
|
+
result_type = Type.DATE
|
|
310
|
+
if needs_time_of_day:
|
|
311
|
+
result_type = Type.DATETIME
|
|
312
|
+
|
|
313
|
+
result_dtype = to_numpy_dtype(result_type)
|
|
314
|
+
flat_starts = period_starts.to_numpy(dtype=result_dtype)
|
|
315
|
+
date_periods = flat_starts.reshape(values.shape)
|
|
316
|
+
|
|
317
|
+
return date_periods
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def count_durations(values: NDArray[Any], unit: DurationUnit, function_name: str) -> NDArray[numpy.float64]:
|
|
321
|
+
"""
|
|
322
|
+
Return each duration counted in a unit.
|
|
323
|
+
|
|
324
|
+
.. versionadded:: 0.1.0
|
|
325
|
+
|
|
326
|
+
Parameters
|
|
327
|
+
----------
|
|
328
|
+
values
|
|
329
|
+
The values of a duration Array.
|
|
330
|
+
unit
|
|
331
|
+
The unit to count in.
|
|
332
|
+
function_name
|
|
333
|
+
Name of the function, shown in error messages.
|
|
334
|
+
|
|
335
|
+
Returns
|
|
336
|
+
-------
|
|
337
|
+
NDArray[numpy.float64]
|
|
338
|
+
The number of units of each duration, NaN for a missing value.
|
|
339
|
+
|
|
340
|
+
Raises
|
|
341
|
+
------
|
|
342
|
+
IncompatibleTypesError
|
|
343
|
+
When the values are not durations.
|
|
344
|
+
|
|
345
|
+
Examples
|
|
346
|
+
--------
|
|
347
|
+
>>> import numpy
|
|
348
|
+
>>> import numdaplot as ndp
|
|
349
|
+
>>> from numdaplot.arrays.calculation.time_function_values import count_durations
|
|
350
|
+
>>> count_durations(numpy.array([36], dtype="timedelta64[h]"), ndp.DurationUnit.DAY, "DurationIn")
|
|
351
|
+
array([1.5])
|
|
352
|
+
"""
|
|
353
|
+
require_family(values, DURATION_FAMILIES, function_name)
|
|
354
|
+
unit_code = DURATION_UNIT_CODES[unit]
|
|
355
|
+
one_unit = numpy.timedelta64(1, unit_code)
|
|
356
|
+
counts = numpy.divide(values, one_unit, dtype=numpy.float64)
|
|
357
|
+
|
|
358
|
+
return counts
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def build_durations(values: NDArray[Any], unit: DurationUnit, function_name: str) -> NDArray[numpy.timedelta64]:
|
|
362
|
+
"""
|
|
363
|
+
Return each number read as a duration in a unit, rounded to the nanosecond.
|
|
364
|
+
|
|
365
|
+
.. versionadded:: 0.1.0
|
|
366
|
+
|
|
367
|
+
Parameters
|
|
368
|
+
----------
|
|
369
|
+
values
|
|
370
|
+
The values of a number Array.
|
|
371
|
+
unit
|
|
372
|
+
The unit of the numbers.
|
|
373
|
+
function_name
|
|
374
|
+
Name of the function, shown in error messages.
|
|
375
|
+
|
|
376
|
+
Returns
|
|
377
|
+
-------
|
|
378
|
+
NDArray[numpy.timedelta64]
|
|
379
|
+
Durations in nanoseconds, NaT for a missing value.
|
|
380
|
+
|
|
381
|
+
Raises
|
|
382
|
+
------
|
|
383
|
+
IncompatibleTypesError
|
|
384
|
+
When the values are not numbers.
|
|
385
|
+
TimeOverflowError
|
|
386
|
+
When a duration is outside the range of nanoseconds, about 292 years.
|
|
387
|
+
|
|
388
|
+
Examples
|
|
389
|
+
--------
|
|
390
|
+
>>> import numpy
|
|
391
|
+
>>> import numdaplot as ndp
|
|
392
|
+
>>> from numdaplot.arrays.calculation.time_function_values import build_durations
|
|
393
|
+
>>> build_durations(numpy.array([1.5, numpy.nan]), ndp.DurationUnit.DAY, "ToDuration")
|
|
394
|
+
array([129600000000000, 'NaT'], dtype='timedelta64[ns]')
|
|
395
|
+
"""
|
|
396
|
+
require_family(values, NUMBER_FAMILIES, function_name)
|
|
397
|
+
unit_code = DURATION_UNIT_CODES[unit]
|
|
398
|
+
one_unit = numpy.timedelta64(1, unit_code)
|
|
399
|
+
one_nanosecond = numpy.timedelta64(1, NANOSECOND_CODE)
|
|
400
|
+
unit_ratio = one_unit // one_nanosecond
|
|
401
|
+
nanoseconds_per_unit = int(unit_ratio)
|
|
402
|
+
duration_dtype = to_numpy_dtype(Type.DURATION)
|
|
403
|
+
if values.dtype.kind in WHOLE_NUMBER_KINDS:
|
|
404
|
+
require_whole_durations_fit(values, nanoseconds_per_unit, function_name)
|
|
405
|
+
whole_values = values.astype(numpy.int64)
|
|
406
|
+
whole_nanoseconds = whole_values * nanoseconds_per_unit
|
|
407
|
+
whole_durations = whole_nanoseconds.astype(duration_dtype)
|
|
408
|
+
return whole_durations
|
|
409
|
+
|
|
410
|
+
missing = numpy.isnan(values)
|
|
411
|
+
decimal_nanoseconds = values * nanoseconds_per_unit
|
|
412
|
+
require_decimal_durations_fit(decimal_nanoseconds, function_name)
|
|
413
|
+
rounded_nanoseconds = numpy.round(decimal_nanoseconds)
|
|
414
|
+
present_nanoseconds = numpy.where(missing, 0, rounded_nanoseconds)
|
|
415
|
+
nanosecond_counts = present_nanoseconds.astype(numpy.int64)
|
|
416
|
+
durations = nanosecond_counts.astype(duration_dtype)
|
|
417
|
+
durations[missing] = numpy.timedelta64(NOT_A_TIME, NANOSECOND_CODE)
|
|
418
|
+
|
|
419
|
+
return durations
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Text shown for an Array.
|
|
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.arrays.conversion.time_text import format_datetimes, format_durations, format_times
|
|
13
|
+
from numdaplot.data_types.numpy_mapping import from_numpy_dtype
|
|
14
|
+
from numdaplot.data_types.type import Type
|
|
15
|
+
|
|
16
|
+
ARRAY_PREFIX = "Array("
|
|
17
|
+
ARRAY_TEXT = ARRAY_PREFIX + "{values}, dtype={type_name})"
|
|
18
|
+
VALUE_SEPARATOR = ", "
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def format_array(values: NDArray[Any]) -> str:
|
|
22
|
+
"""
|
|
23
|
+
Return the text of an Array: its values as nested lists, then its type.
|
|
24
|
+
|
|
25
|
+
Rows of a two-dimensional Array are aligned on separate lines, and long Arrays are shortened with ``...``.
|
|
26
|
+
Datetimes are written as ``"2026-01-02 10:30:00"``, durations as pandas writes them, ``"1 days 12:00:00"``, and
|
|
27
|
+
times of day as ``"15:35:00"``.
|
|
28
|
+
|
|
29
|
+
.. versionadded:: 0.1.0
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
values
|
|
34
|
+
The values of an Array.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
str
|
|
39
|
+
The text, such as ``Array([1, 2, 3], dtype=INT64)``.
|
|
40
|
+
|
|
41
|
+
Examples
|
|
42
|
+
--------
|
|
43
|
+
>>> import numpy
|
|
44
|
+
>>> from numdaplot.arrays.conversion.array_text import format_array
|
|
45
|
+
>>> format_array(numpy.array([1, 2, 3]))
|
|
46
|
+
'Array([1, 2, 3], dtype=INT64)'
|
|
47
|
+
"""
|
|
48
|
+
array_type = from_numpy_dtype(values.dtype)
|
|
49
|
+
shown_values = values
|
|
50
|
+
if array_type == Type.DATETIME:
|
|
51
|
+
shown_values = format_datetimes(values)
|
|
52
|
+
|
|
53
|
+
if array_type == Type.DURATION:
|
|
54
|
+
shown_values = format_durations(values)
|
|
55
|
+
|
|
56
|
+
if array_type == Type.TIME:
|
|
57
|
+
shown_values = format_times(values)
|
|
58
|
+
|
|
59
|
+
values_text = numpy.array2string(shown_values, separator=VALUE_SEPARATOR, prefix=ARRAY_PREFIX)
|
|
60
|
+
array_text = ARRAY_TEXT.format(values=values_text, type_name=array_type.name)
|
|
61
|
+
|
|
62
|
+
return array_text
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Comparison of the values of two Arrays.
|
|
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.arrays.selection.missing_mask import find_missing
|
|
13
|
+
from numdaplot.arrays.type_match import TypeMatch
|
|
14
|
+
from numdaplot.data_types.numpy_mapping import from_numpy_dtype
|
|
15
|
+
from numdaplot.data_types.value_family import find_family
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def are_equal(left: NDArray[Any], right: NDArray[Any], types: TypeMatch) -> bool:
|
|
19
|
+
"""
|
|
20
|
+
Return whether two Arrays hold the same values at the same positions.
|
|
21
|
+
|
|
22
|
+
Two missing values at the same position are equal. Values of types that cannot be compared,
|
|
23
|
+
such as numbers and texts, are never equal.
|
|
24
|
+
|
|
25
|
+
.. versionadded:: 0.1.0
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
left
|
|
30
|
+
The values of the first Array.
|
|
31
|
+
right
|
|
32
|
+
The values of the second Array.
|
|
33
|
+
types
|
|
34
|
+
Whether the types must also be the same.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
bool
|
|
39
|
+
True when the shapes and the values are the same, and the types too with ``TypeMatch.STRICT``.
|
|
40
|
+
|
|
41
|
+
Examples
|
|
42
|
+
--------
|
|
43
|
+
>>> import numpy
|
|
44
|
+
>>> import numdaplot as ndp
|
|
45
|
+
>>> from numdaplot.arrays.conversion.equality_check import are_equal
|
|
46
|
+
>>> are_equal(numpy.array([1, 2]), numpy.array([1.0, 2.0]), ndp.TypeMatch.IGNORED)
|
|
47
|
+
True
|
|
48
|
+
"""
|
|
49
|
+
if left.shape != right.shape:
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
left_type = from_numpy_dtype(left.dtype)
|
|
53
|
+
right_type = from_numpy_dtype(right.dtype)
|
|
54
|
+
different_types = left_type != right_type
|
|
55
|
+
rejects_different_types = types == TypeMatch.STRICT and different_types
|
|
56
|
+
if rejects_different_types:
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
left_family = find_family(left_type)
|
|
60
|
+
right_family = find_family(right_type)
|
|
61
|
+
if left_family != right_family:
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
same_values = left == right
|
|
65
|
+
left_missing = find_missing(left)
|
|
66
|
+
right_missing = find_missing(right)
|
|
67
|
+
both_missing = left_missing & right_missing
|
|
68
|
+
equal_positions = same_values | both_missing
|
|
69
|
+
all_equal = numpy.all(equal_positions)
|
|
70
|
+
is_equal = bool(all_equal)
|
|
71
|
+
|
|
72
|
+
return is_equal
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Conversion of the values of an Array to Python values.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, cast
|
|
8
|
+
|
|
9
|
+
from numpy.typing import NDArray
|
|
10
|
+
|
|
11
|
+
from numdaplot.arrays.selection.missing_mask import find_missing
|
|
12
|
+
from numdaplot.data_types.numpy_mapping import from_numpy_dtype
|
|
13
|
+
from numdaplot.data_types.time_of_day import read_time_objects
|
|
14
|
+
from numdaplot.data_types.type import Type
|
|
15
|
+
|
|
16
|
+
# Python datetimes and timedeltas stop at the microsecond; finer numpy units would become integers.
|
|
17
|
+
PYTHON_TIME_DTYPES = {
|
|
18
|
+
Type.DATETIME: "datetime64[us]",
|
|
19
|
+
Type.DURATION: "timedelta64[us]",
|
|
20
|
+
}
|
|
21
|
+
PYTHON_OBJECT_DTYPE = "object"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def to_python_list(values: NDArray[Any]) -> list[Any]:
|
|
25
|
+
"""
|
|
26
|
+
Return the values as Python values, in nested lists for several dimensions.
|
|
27
|
+
|
|
28
|
+
Datetimes become ``datetime``, dates ``date``, durations ``timedelta``, times of day ``time``, and a missing text,
|
|
29
|
+
date, datetime, duration or time of day becomes ``None``. A missing decimal stays ``nan``.
|
|
30
|
+
|
|
31
|
+
.. versionadded:: 0.1.0
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
values
|
|
36
|
+
The values of an Array.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
list[Any]
|
|
41
|
+
The Python values, one nested list per dimension after the first.
|
|
42
|
+
|
|
43
|
+
Examples
|
|
44
|
+
--------
|
|
45
|
+
>>> import numpy
|
|
46
|
+
>>> from numdaplot.arrays.conversion.python_values import to_python_list
|
|
47
|
+
>>> to_python_list(numpy.array(["2026-01-31T08:30", "NaT"], dtype="datetime64[ns]"))
|
|
48
|
+
[datetime.datetime(2026, 1, 31, 8, 30), None]
|
|
49
|
+
>>> to_python_list(numpy.array(["a", numpy.nan], dtype=numpy.dtypes.StringDType(na_object=numpy.nan)))
|
|
50
|
+
['a', None]
|
|
51
|
+
"""
|
|
52
|
+
array_type = from_numpy_dtype(values.dtype)
|
|
53
|
+
converted_values = values
|
|
54
|
+
if array_type == Type.TIME:
|
|
55
|
+
converted_values = read_time_objects(values)
|
|
56
|
+
|
|
57
|
+
if array_type in PYTHON_TIME_DTYPES:
|
|
58
|
+
python_time_dtype = PYTHON_TIME_DTYPES[array_type]
|
|
59
|
+
converted_values = values.astype(python_time_dtype)
|
|
60
|
+
|
|
61
|
+
if array_type == Type.TEXT:
|
|
62
|
+
missing = find_missing(values)
|
|
63
|
+
# Some versions of the numpy stubs refuse None as a value of an object array.
|
|
64
|
+
converted_values = cast(Any, values.astype(PYTHON_OBJECT_DTYPE))
|
|
65
|
+
converted_values[missing] = None
|
|
66
|
+
|
|
67
|
+
raw_values = converted_values.tolist()
|
|
68
|
+
python_values = cast(list[Any], raw_values)
|
|
69
|
+
|
|
70
|
+
return python_values
|