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,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rows and columns of a Table chosen by a Region.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
import numpy
|
|
10
|
+
import pandas
|
|
11
|
+
from numpy.typing import NDArray
|
|
12
|
+
|
|
13
|
+
from numdaplot.arrays.selection.region_index import find_positions
|
|
14
|
+
from numdaplot.positions.index import Index
|
|
15
|
+
from numdaplot.positions.range import Range
|
|
16
|
+
from numdaplot.positions.region import Region
|
|
17
|
+
from numdaplot.tables.columns.column_names import require_known_columns, require_unique_names
|
|
18
|
+
|
|
19
|
+
POSITION_DTYPE = numpy.int64
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def take_region(frame: pandas.DataFrame, region: Region) -> pandas.DataFrame:
|
|
23
|
+
"""
|
|
24
|
+
Return the rows and the columns of a Table chosen by a Region.
|
|
25
|
+
|
|
26
|
+
.. versionadded:: 0.1.0
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
frame
|
|
31
|
+
The columns of a Table.
|
|
32
|
+
region
|
|
33
|
+
The rows and the columns to take, every one of a dimension when omitted.
|
|
34
|
+
|
|
35
|
+
Returns
|
|
36
|
+
-------
|
|
37
|
+
pandas.DataFrame
|
|
38
|
+
The chosen part, rows numbered from 0, columns in the order of the region.
|
|
39
|
+
|
|
40
|
+
Raises
|
|
41
|
+
------
|
|
42
|
+
InvalidPositionError
|
|
43
|
+
When a position is not a whole number inside its dimension.
|
|
44
|
+
ColumnNotFoundError
|
|
45
|
+
When a column name matches no column.
|
|
46
|
+
DuplicateColumnError
|
|
47
|
+
When a column name appears twice in the region.
|
|
48
|
+
|
|
49
|
+
Examples
|
|
50
|
+
--------
|
|
51
|
+
>>> import pandas
|
|
52
|
+
>>> import numdaplot as ndp
|
|
53
|
+
>>> from numdaplot.tables.frames.region_positions import take_region
|
|
54
|
+
>>> frame = pandas.DataFrame({"city": ["Paris", "Lyon"], "price": [1.5, 8.0]})
|
|
55
|
+
>>> take_region(frame, ndp.Region(rows=ndp.Index(-1), columns=["price"]))
|
|
56
|
+
price
|
|
57
|
+
0 8.0
|
|
58
|
+
"""
|
|
59
|
+
row_count = len(frame)
|
|
60
|
+
row_positions = find_positions(region.rows, row_count)
|
|
61
|
+
column_names = [str(column_name) for column_name in frame.columns]
|
|
62
|
+
column_positions = find_column_positions(region.columns, column_names)
|
|
63
|
+
region_frame = frame.iloc[row_positions, column_positions]
|
|
64
|
+
numbered_frame = region_frame.reset_index(drop=True)
|
|
65
|
+
|
|
66
|
+
return numbered_frame
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def find_column_positions(columns: Index | Range | list[str] | None, column_names: list[str]) -> NDArray[Any]:
|
|
70
|
+
"""
|
|
71
|
+
Return the positions of the columns chosen by a Region.
|
|
72
|
+
|
|
73
|
+
.. versionadded:: 0.1.0
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
columns
|
|
78
|
+
One position, a sequence of positions, a list of names, or ``None`` for every column.
|
|
79
|
+
column_names
|
|
80
|
+
The names of the columns of the Table.
|
|
81
|
+
|
|
82
|
+
Returns
|
|
83
|
+
-------
|
|
84
|
+
NDArray
|
|
85
|
+
The chosen positions, in the order of the region.
|
|
86
|
+
|
|
87
|
+
Raises
|
|
88
|
+
------
|
|
89
|
+
InvalidPositionError
|
|
90
|
+
When a position is not a whole number inside the columns.
|
|
91
|
+
ColumnNotFoundError
|
|
92
|
+
When a name matches no column.
|
|
93
|
+
DuplicateColumnError
|
|
94
|
+
When a name appears twice.
|
|
95
|
+
|
|
96
|
+
Examples
|
|
97
|
+
--------
|
|
98
|
+
>>> from numdaplot.tables.frames.region_positions import find_column_positions
|
|
99
|
+
>>> find_column_positions(["price", "city"], ["city", "price"])
|
|
100
|
+
array([1, 0])
|
|
101
|
+
"""
|
|
102
|
+
if not isinstance(columns, list):
|
|
103
|
+
column_count = len(column_names)
|
|
104
|
+
positions = find_positions(columns, column_count)
|
|
105
|
+
return positions
|
|
106
|
+
|
|
107
|
+
require_unique_names(columns)
|
|
108
|
+
require_known_columns(columns, column_names)
|
|
109
|
+
positions_by_name = {column_name: position for position, column_name in enumerate(column_names)}
|
|
110
|
+
named_positions = [positions_by_name[column_name] for column_name in columns]
|
|
111
|
+
positions = numpy.array(named_positions, dtype=POSITION_DTYPE)
|
|
112
|
+
|
|
113
|
+
return positions
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Text of a Table, with the type of each column under its name.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from shutil import get_terminal_size
|
|
8
|
+
|
|
9
|
+
import pandas
|
|
10
|
+
|
|
11
|
+
from numdaplot.tables.frames.column_values import find_column_type
|
|
12
|
+
from numdaplot.tables.frames.time_columns import is_time_column, write_time_texts_column
|
|
13
|
+
from numdaplot.tables.frames.time_zones import name_column_type
|
|
14
|
+
from numdaplot.tables.preview.shown_columns import ShownColumns
|
|
15
|
+
|
|
16
|
+
MAX_COLUMNS_OPTION = "display.max_columns"
|
|
17
|
+
WIDTH_OPTION = "display.width"
|
|
18
|
+
# In pandas, no limit shows every column, and a limit of 0 only shows those fitting in the width.
|
|
19
|
+
NO_ROWS_NOTE = "(0 rows)"
|
|
20
|
+
NO_COLUMNS_NOTE = "(no columns, {rows_text})"
|
|
21
|
+
ONE_ROW_TEXT = "1 row"
|
|
22
|
+
ROWS_TEXT = "{row_count} rows"
|
|
23
|
+
BLANK_CELL = ""
|
|
24
|
+
BLANK_ROW_START = "0"
|
|
25
|
+
LINE_BREAK = "\n"
|
|
26
|
+
SHOW_DIMENSIONS_OPTION = "display.show_dimensions"
|
|
27
|
+
COLUMN_LIMITS = {
|
|
28
|
+
ShownColumns.ALL: None,
|
|
29
|
+
ShownColumns.COMPACT: 0,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def build_typed_frame(frame: pandas.DataFrame) -> pandas.DataFrame:
|
|
34
|
+
"""
|
|
35
|
+
Return a copy of the columns of a Table whose header shows the name, then the type, of each column.
|
|
36
|
+
|
|
37
|
+
.. versionadded:: 0.1.0
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
frame
|
|
42
|
+
The columns of a Table.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
pandas.DataFrame
|
|
47
|
+
A copy with a two-level header: the column names, then the names of their ``ndp.Type``, followed by
|
|
48
|
+
the time zone of a datetime column that has one.
|
|
49
|
+
|
|
50
|
+
Examples
|
|
51
|
+
--------
|
|
52
|
+
>>> import pandas
|
|
53
|
+
>>> from numdaplot.tables.frames.table_text import build_typed_frame
|
|
54
|
+
>>> build_typed_frame(pandas.DataFrame({"price": [1.5]})).columns.tolist()
|
|
55
|
+
[('price', 'FLOAT64')]
|
|
56
|
+
"""
|
|
57
|
+
column_names = list(frame.columns)
|
|
58
|
+
type_names = list[str]()
|
|
59
|
+
|
|
60
|
+
for column_name in column_names:
|
|
61
|
+
column = frame[column_name]
|
|
62
|
+
column_type = find_column_type(column)
|
|
63
|
+
type_name = name_column_type(column, column_type)
|
|
64
|
+
type_names.append(type_name)
|
|
65
|
+
|
|
66
|
+
header = pandas.MultiIndex.from_arrays([column_names, type_names])
|
|
67
|
+
typed_frame = frame.copy()
|
|
68
|
+
for column_name in column_names:
|
|
69
|
+
column = frame[column_name]
|
|
70
|
+
if is_time_column(column):
|
|
71
|
+
typed_frame[column_name] = write_time_texts_column(column)
|
|
72
|
+
|
|
73
|
+
typed_frame.columns = header
|
|
74
|
+
|
|
75
|
+
return typed_frame
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def format_table(frame: pandas.DataFrame, shown_columns: ShownColumns = ShownColumns.ALL) -> str:
|
|
79
|
+
"""
|
|
80
|
+
Return the text pandas shows for the columns of a Table, with the type of each column under its name.
|
|
81
|
+
|
|
82
|
+
A long Table only shows its first and last rows, following the pandas display settings. The columns follow the
|
|
83
|
+
width of the terminal, whatever the pandas display settings.
|
|
84
|
+
|
|
85
|
+
.. versionadded:: 0.1.0
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
frame
|
|
90
|
+
The columns of a Table.
|
|
91
|
+
shown_columns
|
|
92
|
+
``ShownColumns.ALL`` by default for every column, going on after a line break when they do not fit, or
|
|
93
|
+
``ShownColumns.COMPACT`` to replace those that do not fit by ``...``.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
str
|
|
98
|
+
The text of the Table, with row numbers on the left.
|
|
99
|
+
|
|
100
|
+
Examples
|
|
101
|
+
--------
|
|
102
|
+
>>> import pandas
|
|
103
|
+
>>> from numdaplot.tables.frames.table_text import format_table
|
|
104
|
+
>>> print(format_table(pandas.DataFrame({"price": [1.5, 8.0]})))
|
|
105
|
+
price
|
|
106
|
+
FLOAT64
|
|
107
|
+
0 1.5
|
|
108
|
+
1 8.0
|
|
109
|
+
"""
|
|
110
|
+
empty_table_text = format_empty_table(frame, shown_columns)
|
|
111
|
+
if empty_table_text is not None:
|
|
112
|
+
return empty_table_text
|
|
113
|
+
|
|
114
|
+
typed_frame = build_typed_frame(frame)
|
|
115
|
+
column_limit = COLUMN_LIMITS[shown_columns]
|
|
116
|
+
terminal_size = get_terminal_size()
|
|
117
|
+
with pandas.option_context(MAX_COLUMNS_OPTION, column_limit, WIDTH_OPTION, terminal_size.columns):
|
|
118
|
+
table_text = repr(typed_frame)
|
|
119
|
+
|
|
120
|
+
return table_text
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def write_empty_table_note(frame: pandas.DataFrame) -> str | None:
|
|
124
|
+
"""
|
|
125
|
+
Return the note replacing the rows of a Table without rows or without columns.
|
|
126
|
+
|
|
127
|
+
.. versionadded:: 0.1.0
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
frame
|
|
132
|
+
The columns of a Table.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
str or None
|
|
137
|
+
``(0 rows)``, ``(no columns, 2 rows)``, or None for a Table with values.
|
|
138
|
+
|
|
139
|
+
Examples
|
|
140
|
+
--------
|
|
141
|
+
>>> import pandas
|
|
142
|
+
>>> from numdaplot.tables.frames.table_text import write_empty_table_note
|
|
143
|
+
>>> write_empty_table_note(pandas.DataFrame({"price": [1.5]})) is None
|
|
144
|
+
True
|
|
145
|
+
>>> write_empty_table_note(pandas.DataFrame(index=[0, 1]))
|
|
146
|
+
'(no columns, 2 rows)'
|
|
147
|
+
>>> write_empty_table_note(pandas.DataFrame(index=[0]))
|
|
148
|
+
'(no columns, 1 row)'
|
|
149
|
+
"""
|
|
150
|
+
row_count = len(frame.index)
|
|
151
|
+
column_count = len(frame.columns)
|
|
152
|
+
if column_count == 0:
|
|
153
|
+
rows_text = ONE_ROW_TEXT if row_count == 1 else ROWS_TEXT.format(row_count=row_count)
|
|
154
|
+
no_columns_note = NO_COLUMNS_NOTE.format(rows_text=rows_text)
|
|
155
|
+
return no_columns_note
|
|
156
|
+
|
|
157
|
+
if row_count == 0:
|
|
158
|
+
return NO_ROWS_NOTE
|
|
159
|
+
|
|
160
|
+
return None
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def format_empty_table(frame: pandas.DataFrame, shown_columns: ShownColumns) -> str | None:
|
|
164
|
+
"""
|
|
165
|
+
Return the text of a Table without rows or without columns: its header if any, then a note.
|
|
166
|
+
|
|
167
|
+
pandas writes such a Table with its own words, so the header comes from a Table of one blank row.
|
|
168
|
+
|
|
169
|
+
.. versionadded:: 0.1.0
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
frame
|
|
174
|
+
The columns of a Table.
|
|
175
|
+
shown_columns
|
|
176
|
+
``ShownColumns.ALL`` for every column, or ``ShownColumns.COMPACT`` to replace those that do not fit by ``...``.
|
|
177
|
+
|
|
178
|
+
Returns
|
|
179
|
+
-------
|
|
180
|
+
str or None
|
|
181
|
+
The text, or None for a Table with values.
|
|
182
|
+
|
|
183
|
+
Examples
|
|
184
|
+
--------
|
|
185
|
+
>>> import pandas
|
|
186
|
+
>>> from numdaplot.tables.frames.table_text import format_empty_table
|
|
187
|
+
>>> from numdaplot.tables.preview.shown_columns import ShownColumns
|
|
188
|
+
>>> prices = pandas.DataFrame({"price": pandas.Series(dtype="float64")})
|
|
189
|
+
>>> print(format_empty_table(prices, ShownColumns.ALL))
|
|
190
|
+
price
|
|
191
|
+
FLOAT64
|
|
192
|
+
(0 rows)
|
|
193
|
+
"""
|
|
194
|
+
note = write_empty_table_note(frame)
|
|
195
|
+
if note is None:
|
|
196
|
+
return None
|
|
197
|
+
|
|
198
|
+
column_count = len(frame.columns)
|
|
199
|
+
if column_count == 0:
|
|
200
|
+
return note
|
|
201
|
+
|
|
202
|
+
typed_frame = build_typed_frame(frame)
|
|
203
|
+
blank_row = [[BLANK_CELL] * column_count]
|
|
204
|
+
blank_frame = pandas.DataFrame(blank_row, columns=typed_frame.columns)
|
|
205
|
+
column_limit = COLUMN_LIMITS[shown_columns]
|
|
206
|
+
terminal_size = get_terminal_size()
|
|
207
|
+
with pandas.option_context(
|
|
208
|
+
MAX_COLUMNS_OPTION,
|
|
209
|
+
column_limit,
|
|
210
|
+
WIDTH_OPTION,
|
|
211
|
+
terminal_size.columns,
|
|
212
|
+
SHOW_DIMENSIONS_OPTION,
|
|
213
|
+
False,
|
|
214
|
+
):
|
|
215
|
+
blank_text = repr(blank_frame)
|
|
216
|
+
|
|
217
|
+
lines = blank_text.splitlines()
|
|
218
|
+
header_lines = [line for line in lines if not line.startswith(BLANK_ROW_START)]
|
|
219
|
+
empty_table_lines = [*header_lines, note]
|
|
220
|
+
empty_table_text = LINE_BREAK.join(empty_table_lines)
|
|
221
|
+
|
|
222
|
+
return empty_table_text
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Table columns of times of day, and the durations a Table reads from outside numdaplot.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, cast
|
|
8
|
+
|
|
9
|
+
import numpy
|
|
10
|
+
import pandas
|
|
11
|
+
from numpy.typing import NDArray
|
|
12
|
+
|
|
13
|
+
from numdaplot.arrays.conversion.time_text import format_times
|
|
14
|
+
from numdaplot.data_types.time_of_day import TIME_DTYPE, read_time_objects, store_time_objects
|
|
15
|
+
from numdaplot.tables.frames.column import Column
|
|
16
|
+
from numdaplot.tables.frames.time_range_errors import TimeRangeErrors
|
|
17
|
+
|
|
18
|
+
DURATION_KIND = "m"
|
|
19
|
+
NANOSECOND_DURATION_DTYPE = numpy.dtype("timedelta64[ns]")
|
|
20
|
+
PYTHON_OBJECT_DTYPE = numpy.dtype(object)
|
|
21
|
+
TEXT_PANDAS_DTYPE = "string"
|
|
22
|
+
TABLE_CREATION_OPERATION = "Table creation"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def is_time_column(column: Column) -> bool:
|
|
26
|
+
"""
|
|
27
|
+
Return whether a Table column stores times of day.
|
|
28
|
+
|
|
29
|
+
.. versionadded:: 0.1.0
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
column
|
|
34
|
+
A Table column.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
bool
|
|
39
|
+
True for a column in ``timedelta64[us]``.
|
|
40
|
+
|
|
41
|
+
Examples
|
|
42
|
+
--------
|
|
43
|
+
>>> import pandas
|
|
44
|
+
>>> from numdaplot.tables.frames.time_columns import is_time_column
|
|
45
|
+
>>> import numpy
|
|
46
|
+
>>> is_time_column(pandas.Series(numpy.array([1], dtype="timedelta64[us]"))), is_time_column(pandas.Series([1]))
|
|
47
|
+
(True, False)
|
|
48
|
+
"""
|
|
49
|
+
holds_times = column.dtype == TIME_DTYPE
|
|
50
|
+
|
|
51
|
+
return holds_times
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def read_time_objects_column(column: Column) -> Column:
|
|
55
|
+
"""
|
|
56
|
+
Return a column of times of day as Python ``datetime.time`` objects, None where missing.
|
|
57
|
+
|
|
58
|
+
.. versionadded:: 0.1.0
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
column
|
|
63
|
+
A Table column of times of day.
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
Column
|
|
68
|
+
An object column with the same index.
|
|
69
|
+
|
|
70
|
+
Examples
|
|
71
|
+
--------
|
|
72
|
+
>>> import pandas
|
|
73
|
+
>>> from numdaplot.tables.frames.time_columns import read_time_objects_column
|
|
74
|
+
>>> import numpy
|
|
75
|
+
>>> minutes = pandas.Series(numpy.array([60000000], dtype="timedelta64[us]"))
|
|
76
|
+
>>> read_time_objects_column(minutes).tolist()
|
|
77
|
+
[datetime.time(0, 1)]
|
|
78
|
+
"""
|
|
79
|
+
stored_times = column.to_numpy(dtype=TIME_DTYPE)
|
|
80
|
+
time_objects = read_time_objects(stored_times)
|
|
81
|
+
object_column = pandas.Series(time_objects, index=column.index, name=column.name, dtype=PYTHON_OBJECT_DTYPE)
|
|
82
|
+
|
|
83
|
+
return object_column
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def store_time_column(column: Column) -> Column:
|
|
87
|
+
"""
|
|
88
|
+
Return a column of Python times of day stored as the time since midnight.
|
|
89
|
+
|
|
90
|
+
.. versionadded:: 0.1.0
|
|
91
|
+
|
|
92
|
+
Parameters
|
|
93
|
+
----------
|
|
94
|
+
column
|
|
95
|
+
An object column of ``datetime.time`` and missing values.
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
Column
|
|
100
|
+
A column in ``timedelta64[us]`` with the same index, NaT where missing.
|
|
101
|
+
|
|
102
|
+
Examples
|
|
103
|
+
--------
|
|
104
|
+
>>> from datetime import time
|
|
105
|
+
>>> import pandas
|
|
106
|
+
>>> from numdaplot.tables.frames.time_columns import store_time_column
|
|
107
|
+
>>> store_time_column(pandas.Series([time(0, 1), None], dtype=object)).tolist()
|
|
108
|
+
[Timedelta('0 days 00:01:00'), NaT]
|
|
109
|
+
"""
|
|
110
|
+
object_values = read_object_values(column)
|
|
111
|
+
stored_times = store_time_objects(object_values)
|
|
112
|
+
time_column = pandas.Series(stored_times, index=column.index, name=column.name)
|
|
113
|
+
|
|
114
|
+
return time_column
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def read_object_values(column: Column) -> NDArray[Any]:
|
|
118
|
+
"""
|
|
119
|
+
Return the values of a column as Python objects, None where missing.
|
|
120
|
+
|
|
121
|
+
.. versionadded:: 0.1.0
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
column
|
|
126
|
+
A column of any dtype.
|
|
127
|
+
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
NDArray
|
|
131
|
+
An object array, None for every missing marker such as NaN or ``pd.NA``.
|
|
132
|
+
|
|
133
|
+
Examples
|
|
134
|
+
--------
|
|
135
|
+
>>> import pandas
|
|
136
|
+
>>> from numdaplot.tables.frames.time_columns import read_object_values
|
|
137
|
+
>>> read_object_values(pandas.Series(["a", float("nan")], dtype=object))
|
|
138
|
+
array(['a', None], dtype=object)
|
|
139
|
+
"""
|
|
140
|
+
missing = column.isna()
|
|
141
|
+
missing_flags = missing.to_numpy(dtype=bool)
|
|
142
|
+
# Some versions of the numpy stubs refuse None as a value of an object array.
|
|
143
|
+
object_values = cast(Any, column.to_numpy(dtype=PYTHON_OBJECT_DTYPE, copy=True))
|
|
144
|
+
object_values[missing_flags] = None
|
|
145
|
+
|
|
146
|
+
return object_values
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def convert_outside_durations(frame: pandas.DataFrame) -> pandas.DataFrame:
|
|
150
|
+
"""
|
|
151
|
+
Return a DataFrame read from outside numdaplot whose durations, of any unit, are stored in nanoseconds.
|
|
152
|
+
|
|
153
|
+
Microseconds store the times of day, so an outside duration in microseconds must not keep them.
|
|
154
|
+
|
|
155
|
+
.. versionadded:: 0.1.0
|
|
156
|
+
|
|
157
|
+
Parameters
|
|
158
|
+
----------
|
|
159
|
+
frame
|
|
160
|
+
A DataFrame read from a file or given by the user. It is not changed.
|
|
161
|
+
|
|
162
|
+
Returns
|
|
163
|
+
-------
|
|
164
|
+
pandas.DataFrame
|
|
165
|
+
The DataFrame, a copy with its duration columns in ``timedelta64[ns]`` when it has some.
|
|
166
|
+
|
|
167
|
+
Raises
|
|
168
|
+
------
|
|
169
|
+
TimeOverflowError
|
|
170
|
+
When a duration is beyond about 292 years, which nanoseconds cannot hold.
|
|
171
|
+
|
|
172
|
+
Examples
|
|
173
|
+
--------
|
|
174
|
+
>>> import pandas
|
|
175
|
+
>>> from numdaplot.tables.frames.time_columns import convert_outside_durations
|
|
176
|
+
>>> import numpy
|
|
177
|
+
>>> frame = pandas.DataFrame({"wait": numpy.array([5], dtype="timedelta64[us]")})
|
|
178
|
+
>>> convert_outside_durations(frame).dtypes.tolist()
|
|
179
|
+
[dtype('<m8[ns]')]
|
|
180
|
+
"""
|
|
181
|
+
duration_names = [name for name in frame.columns if frame[name].dtype.kind == DURATION_KIND]
|
|
182
|
+
if duration_names == []:
|
|
183
|
+
return frame
|
|
184
|
+
|
|
185
|
+
converted_frame = frame.copy(deep=False)
|
|
186
|
+
for column_name in duration_names:
|
|
187
|
+
column = frame[column_name]
|
|
188
|
+
duration_values = column.to_numpy()
|
|
189
|
+
nanosecond_values = convert_to_nanoseconds(duration_values, str(column_name))
|
|
190
|
+
nanosecond_column = pandas.Series(nanosecond_values, index=column.index, name=column.name)
|
|
191
|
+
converted_frame[column_name] = nanosecond_column
|
|
192
|
+
|
|
193
|
+
return converted_frame
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def convert_to_nanoseconds(durations: NDArray[Any], column_name: str) -> NDArray[Any]:
|
|
197
|
+
"""
|
|
198
|
+
Return durations of any unit in nanoseconds, refusing those that nanoseconds cannot hold.
|
|
199
|
+
|
|
200
|
+
.. versionadded:: 0.1.0
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
durations
|
|
205
|
+
Durations in ``timedelta64`` of any unit.
|
|
206
|
+
column_name
|
|
207
|
+
The name of the column holding them, named by the error.
|
|
208
|
+
|
|
209
|
+
Returns
|
|
210
|
+
-------
|
|
211
|
+
NDArray
|
|
212
|
+
The durations in ``timedelta64[ns]``.
|
|
213
|
+
|
|
214
|
+
Raises
|
|
215
|
+
------
|
|
216
|
+
TimeOverflowError
|
|
217
|
+
When a duration is beyond about 292 years.
|
|
218
|
+
|
|
219
|
+
Examples
|
|
220
|
+
--------
|
|
221
|
+
>>> import numpy
|
|
222
|
+
>>> from numdaplot.tables.frames.time_columns import convert_to_nanoseconds
|
|
223
|
+
>>> convert_to_nanoseconds(numpy.array([2], dtype="timedelta64[s]"), "wait")
|
|
224
|
+
array([2000000000], dtype='timedelta64[ns]')
|
|
225
|
+
"""
|
|
226
|
+
with TimeRangeErrors(TABLE_CREATION_OPERATION, column_name):
|
|
227
|
+
try:
|
|
228
|
+
nanosecond_values = durations.astype(NANOSECOND_DURATION_DTYPE)
|
|
229
|
+
except OverflowError as error:
|
|
230
|
+
raise pandas.errors.OutOfBoundsTimedelta from error
|
|
231
|
+
|
|
232
|
+
# Some versions of numpy wrap a duration beyond the range of nanoseconds instead of raising.
|
|
233
|
+
original_values = nanosecond_values.astype(durations.dtype)
|
|
234
|
+
is_kept = (original_values == durations) | numpy.isnat(durations)
|
|
235
|
+
is_exact = bool(is_kept.all())
|
|
236
|
+
if not is_exact:
|
|
237
|
+
raise pandas.errors.OutOfBoundsTimedelta
|
|
238
|
+
|
|
239
|
+
return nanosecond_values
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def read_time_objects_frame(frame: pandas.DataFrame) -> pandas.DataFrame:
|
|
243
|
+
"""
|
|
244
|
+
Return a DataFrame whose columns of times of day hold Python ``datetime.time`` objects.
|
|
245
|
+
|
|
246
|
+
.. versionadded:: 0.1.0
|
|
247
|
+
|
|
248
|
+
Parameters
|
|
249
|
+
----------
|
|
250
|
+
frame
|
|
251
|
+
The columns of a Table. It is not changed.
|
|
252
|
+
|
|
253
|
+
Returns
|
|
254
|
+
-------
|
|
255
|
+
pandas.DataFrame
|
|
256
|
+
A deep copy, each column of times of day as an object column.
|
|
257
|
+
|
|
258
|
+
Examples
|
|
259
|
+
--------
|
|
260
|
+
>>> import pandas
|
|
261
|
+
>>> from numdaplot.tables.frames.time_columns import read_time_objects_frame
|
|
262
|
+
>>> import numpy
|
|
263
|
+
>>> frame = pandas.DataFrame({"hour": numpy.array([60000000], dtype="timedelta64[us]")})
|
|
264
|
+
>>> read_time_objects_frame(frame)["hour"].tolist()
|
|
265
|
+
[datetime.time(0, 1)]
|
|
266
|
+
"""
|
|
267
|
+
frame_copy = frame.copy(deep=True)
|
|
268
|
+
for column_name in frame.columns:
|
|
269
|
+
column = frame[column_name]
|
|
270
|
+
if is_time_column(column):
|
|
271
|
+
object_column = read_time_objects_column(column)
|
|
272
|
+
frame_copy[column_name] = object_column
|
|
273
|
+
|
|
274
|
+
return frame_copy
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def write_time_texts_column(column: Column) -> Column:
|
|
278
|
+
"""
|
|
279
|
+
Return a column of times of day as texts, such as ``15:35:00``, ``NaT`` where missing.
|
|
280
|
+
|
|
281
|
+
.. versionadded:: 0.1.0
|
|
282
|
+
|
|
283
|
+
Parameters
|
|
284
|
+
----------
|
|
285
|
+
column
|
|
286
|
+
A Table column of times of day.
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
Column
|
|
291
|
+
An object column of texts with the same index.
|
|
292
|
+
|
|
293
|
+
Examples
|
|
294
|
+
--------
|
|
295
|
+
>>> import pandas
|
|
296
|
+
>>> from numdaplot.tables.frames.time_columns import write_time_texts_column
|
|
297
|
+
>>> import numpy
|
|
298
|
+
>>> hours = pandas.Series(numpy.array([56100000000, "NaT"], dtype="timedelta64[us]"))
|
|
299
|
+
>>> write_time_texts_column(hours).tolist()
|
|
300
|
+
['15:35:00', 'NaT']
|
|
301
|
+
"""
|
|
302
|
+
stored_times = column.to_numpy(dtype=TIME_DTYPE)
|
|
303
|
+
time_texts = format_times(stored_times)
|
|
304
|
+
text_column = pandas.Series(time_texts, index=column.index, name=column.name, dtype=PYTHON_OBJECT_DTYPE)
|
|
305
|
+
|
|
306
|
+
return text_column
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def write_time_texts_frame(frame: pandas.DataFrame) -> pandas.DataFrame:
|
|
310
|
+
"""
|
|
311
|
+
Return a DataFrame whose columns of times of day are written as texts, missing where a time is missing.
|
|
312
|
+
|
|
313
|
+
.. versionadded:: 0.1.0
|
|
314
|
+
|
|
315
|
+
Parameters
|
|
316
|
+
----------
|
|
317
|
+
frame
|
|
318
|
+
The columns of a Table. It is not changed.
|
|
319
|
+
|
|
320
|
+
Returns
|
|
321
|
+
-------
|
|
322
|
+
pandas.DataFrame
|
|
323
|
+
A copy, each column of times of day as texts such as ``15:35:00``.
|
|
324
|
+
|
|
325
|
+
Examples
|
|
326
|
+
--------
|
|
327
|
+
>>> import numpy
|
|
328
|
+
>>> import pandas
|
|
329
|
+
>>> from numdaplot.tables.frames.time_columns import write_time_texts_frame
|
|
330
|
+
>>> frame = pandas.DataFrame({"hour": numpy.array([56100000000, "NaT"], dtype="timedelta64[us]")})
|
|
331
|
+
>>> write_time_texts_frame(frame)["hour"].tolist()
|
|
332
|
+
['15:35:00', <NA>]
|
|
333
|
+
"""
|
|
334
|
+
text_frame = frame.copy()
|
|
335
|
+
for column_name in frame.columns:
|
|
336
|
+
column = frame[column_name]
|
|
337
|
+
if is_time_column(column):
|
|
338
|
+
time_texts = write_time_texts_column(column)
|
|
339
|
+
missing = column.isna()
|
|
340
|
+
# Some versions of the pandas stubs leave the types of mask partly unknown.
|
|
341
|
+
text_column = cast(Any, time_texts)
|
|
342
|
+
present_texts = cast(Column, text_column.mask(missing))
|
|
343
|
+
text_frame[column_name] = present_texts.astype(TEXT_PANDAS_DTYPE)
|
|
344
|
+
|
|
345
|
+
return text_frame
|