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.
Files changed (474) hide show
  1. numdaplot/__init__.py +506 -0
  2. numdaplot/arrays/__init__.py +5 -0
  3. numdaplot/arrays/array.py +92 -0
  4. numdaplot/arrays/array_arithmetic.py +404 -0
  5. numdaplot/arrays/array_calculation.py +143 -0
  6. numdaplot/arrays/array_conversion.py +150 -0
  7. numdaplot/arrays/array_creation.py +371 -0
  8. numdaplot/arrays/array_data.py +281 -0
  9. numdaplot/arrays/array_layout.py +179 -0
  10. numdaplot/arrays/array_logic.py +227 -0
  11. numdaplot/arrays/array_reflected_arithmetic.py +334 -0
  12. numdaplot/arrays/array_refusals.py +339 -0
  13. numdaplot/arrays/array_selection.py +195 -0
  14. numdaplot/arrays/array_sorting.py +59 -0
  15. numdaplot/arrays/axis_number.py +58 -0
  16. numdaplot/arrays/calculation/__init__.py +5 -0
  17. numdaplot/arrays/calculation/counting_statistics.py +325 -0
  18. numdaplot/arrays/calculation/location_statistics.py +268 -0
  19. numdaplot/arrays/calculation/math_function_values.py +183 -0
  20. numdaplot/arrays/calculation/statistic_values.py +209 -0
  21. numdaplot/arrays/calculation/time_function_values.py +419 -0
  22. numdaplot/arrays/conversion/__init__.py +5 -0
  23. numdaplot/arrays/conversion/array_text.py +62 -0
  24. numdaplot/arrays/conversion/equality_check.py +72 -0
  25. numdaplot/arrays/conversion/python_values.py +70 -0
  26. numdaplot/arrays/conversion/time_text.py +290 -0
  27. numdaplot/arrays/creation/__init__.py +5 -0
  28. numdaplot/arrays/creation/date_parts.py +89 -0
  29. numdaplot/arrays/creation/date_parts_values.py +437 -0
  30. numdaplot/arrays/creation/distribution.py +54 -0
  31. numdaplot/arrays/creation/filled_values.py +58 -0
  32. numdaplot/arrays/creation/list_conversion.py +311 -0
  33. numdaplot/arrays/creation/list_shape.py +97 -0
  34. numdaplot/arrays/creation/normal.py +65 -0
  35. numdaplot/arrays/creation/numpy_conversion.py +149 -0
  36. numdaplot/arrays/creation/random_integers.py +104 -0
  37. numdaplot/arrays/creation/random_values.py +97 -0
  38. numdaplot/arrays/creation/range_values.py +73 -0
  39. numdaplot/arrays/creation/spacing.py +84 -0
  40. numdaplot/arrays/creation/spacing_values.py +63 -0
  41. numdaplot/arrays/creation/uniform.py +63 -0
  42. numdaplot/arrays/equality.py +68 -0
  43. numdaplot/arrays/layout/__init__.py +5 -0
  44. numdaplot/arrays/layout/sorting_values.py +113 -0
  45. numdaplot/arrays/layout/unique_values.py +49 -0
  46. numdaplot/arrays/mapping/__init__.py +5 -0
  47. numdaplot/arrays/mapping/mapped_values.py +286 -0
  48. numdaplot/arrays/mapping/unmatched.py +50 -0
  49. numdaplot/arrays/mapping/value_change.py +55 -0
  50. numdaplot/arrays/mapping/value_mapping.py +161 -0
  51. numdaplot/arrays/math_functions/__init__.py +5 -0
  52. numdaplot/arrays/math_functions/absolute.py +27 -0
  53. numdaplot/arrays/math_functions/cosine.py +28 -0
  54. numdaplot/arrays/math_functions/exponential.py +27 -0
  55. numdaplot/arrays/math_functions/logarithm.py +72 -0
  56. numdaplot/arrays/math_functions/math_function.py +58 -0
  57. numdaplot/arrays/math_functions/round.py +58 -0
  58. numdaplot/arrays/math_functions/sine.py +28 -0
  59. numdaplot/arrays/math_functions/square_root.py +27 -0
  60. numdaplot/arrays/operations/__init__.py +5 -0
  61. numdaplot/arrays/operations/boolean_operands.py +48 -0
  62. numdaplot/arrays/operations/combination.py +157 -0
  63. numdaplot/arrays/operations/float_errors.py +170 -0
  64. numdaplot/arrays/operations/integer_bounds.py +175 -0
  65. numdaplot/arrays/operations/integer_rules.py +397 -0
  66. numdaplot/arrays/operations/operand.py +139 -0
  67. numdaplot/arrays/operations/time_arithmetic.py +479 -0
  68. numdaplot/arrays/operations/time_bounds.py +286 -0
  69. numdaplot/arrays/operations/time_result_bounds.py +397 -0
  70. numdaplot/arrays/operations/transformation.py +54 -0
  71. numdaplot/arrays/operations/type_requirements.py +94 -0
  72. numdaplot/arrays/replacement.py +66 -0
  73. numdaplot/arrays/selection/__init__.py +5 -0
  74. numdaplot/arrays/selection/comparison_masks.py +131 -0
  75. numdaplot/arrays/selection/membership_masks.py +118 -0
  76. numdaplot/arrays/selection/missing_mask.py +50 -0
  77. numdaplot/arrays/selection/region_index.py +178 -0
  78. numdaplot/arrays/selection/replaced_values.py +120 -0
  79. numdaplot/arrays/selection/rule_mask.py +83 -0
  80. numdaplot/arrays/selection/time_reference.py +172 -0
  81. numdaplot/arrays/shape.py +74 -0
  82. numdaplot/arrays/type_match.py +51 -0
  83. numdaplot/data_types/__init__.py +5 -0
  84. numdaplot/data_types/library.py +57 -0
  85. numdaplot/data_types/numpy_mapping.py +207 -0
  86. numdaplot/data_types/pandas_mapping.py +114 -0
  87. numdaplot/data_types/time_of_day.py +292 -0
  88. numdaplot/data_types/type.py +224 -0
  89. numdaplot/data_types/value_family.py +149 -0
  90. numdaplot/data_types/value_type.py +147 -0
  91. numdaplot/dates/__init__.py +5 -0
  92. numdaplot/dates/custom_date_format.py +83 -0
  93. numdaplot/dates/date_format.py +120 -0
  94. numdaplot/dates/date_part.py +59 -0
  95. numdaplot/dates/date_part_unit.py +153 -0
  96. numdaplot/dates/date_period.py +57 -0
  97. numdaplot/dates/duration_in.py +58 -0
  98. numdaplot/dates/duration_unit.py +90 -0
  99. numdaplot/dates/period_unit.py +101 -0
  100. numdaplot/dates/time_function.py +56 -0
  101. numdaplot/dates/time_zone.py +68 -0
  102. numdaplot/dates/time_zone_change.py +71 -0
  103. numdaplot/dates/time_zone_mode.py +81 -0
  104. numdaplot/dates/to_duration.py +58 -0
  105. numdaplot/errors/__init__.py +7 -0
  106. numdaplot/errors/broadcast_warning.py +36 -0
  107. numdaplot/errors/calculation_warning.py +35 -0
  108. numdaplot/errors/cell_out_of_range_error.py +77 -0
  109. numdaplot/errors/column_not_found_error.py +64 -0
  110. numdaplot/errors/conflicting_settings_error.py +60 -0
  111. numdaplot/errors/dimension_error.py +62 -0
  112. numdaplot/errors/display_warning.py +32 -0
  113. numdaplot/errors/duplicate_column_error.py +82 -0
  114. numdaplot/errors/duplicate_label_error.py +55 -0
  115. numdaplot/errors/duplicate_statistic_error.py +55 -0
  116. numdaplot/errors/duplicate_value_error.py +54 -0
  117. numdaplot/errors/empty_array_error.py +55 -0
  118. numdaplot/errors/empty_list_error.py +52 -0
  119. numdaplot/errors/empty_region_error.py +34 -0
  120. numdaplot/errors/empty_text_error.py +34 -0
  121. numdaplot/errors/empty_total_error.py +62 -0
  122. numdaplot/errors/empty_values_error.py +34 -0
  123. numdaplot/errors/file_access_error.py +70 -0
  124. numdaplot/errors/file_exists_error.py +62 -0
  125. numdaplot/errors/file_not_found_error.py +56 -0
  126. numdaplot/errors/incompatible_charts_error.py +80 -0
  127. numdaplot/errors/incompatible_types_error.py +104 -0
  128. numdaplot/errors/integer_overflow_error.py +61 -0
  129. numdaplot/errors/invalid_base_error.py +52 -0
  130. numdaplot/errors/invalid_bin_width_error.py +66 -0
  131. numdaplot/errors/invalid_bounds_error.py +58 -0
  132. numdaplot/errors/invalid_chart_data_error.py +81 -0
  133. numdaplot/errors/invalid_color_count_error.py +63 -0
  134. numdaplot/errors/invalid_color_error.py +51 -0
  135. numdaplot/errors/invalid_column_name_error.py +52 -0
  136. numdaplot/errors/invalid_conversion_error.py +119 -0
  137. numdaplot/errors/invalid_count_error.py +61 -0
  138. numdaplot/errors/invalid_date_format_error.py +51 -0
  139. numdaplot/errors/invalid_deviation_error.py +52 -0
  140. numdaplot/errors/invalid_fraction_error.py +51 -0
  141. numdaplot/errors/invalid_label_count_error.py +61 -0
  142. numdaplot/errors/invalid_limits_error.py +111 -0
  143. numdaplot/errors/invalid_opacity_error.py +52 -0
  144. numdaplot/errors/invalid_point_size_error.py +52 -0
  145. numdaplot/errors/invalid_position_error.py +106 -0
  146. numdaplot/errors/invalid_resolution_error.py +51 -0
  147. numdaplot/errors/invalid_rotation_error.py +53 -0
  148. numdaplot/errors/invalid_seed_error.py +53 -0
  149. numdaplot/errors/invalid_separator_error.py +52 -0
  150. numdaplot/errors/invalid_shape_error.py +52 -0
  151. numdaplot/errors/invalid_sheet_name_error.py +54 -0
  152. numdaplot/errors/invalid_size_error.py +58 -0
  153. numdaplot/errors/invalid_step_error.py +77 -0
  154. numdaplot/errors/invalid_suffixes_error.py +61 -0
  155. numdaplot/errors/invalid_time_zone_change_error.py +63 -0
  156. numdaplot/errors/invalid_type_error.py +79 -0
  157. numdaplot/errors/irregular_list_error.py +36 -0
  158. numdaplot/errors/join_relation_error.py +183 -0
  159. numdaplot/errors/missing_dependency_error.py +58 -0
  160. numdaplot/errors/missing_type_error.py +36 -0
  161. numdaplot/errors/missing_value_error.py +62 -0
  162. numdaplot/errors/not_single_value_error.py +53 -0
  163. numdaplot/errors/numdaplot_error.py +25 -0
  164. numdaplot/errors/numdaplot_warning.py +34 -0
  165. numdaplot/errors/occupied_cell_error.py +63 -0
  166. numdaplot/errors/out_of_domain_error.py +70 -0
  167. numdaplot/errors/readability_warning.py +35 -0
  168. numdaplot/errors/refused_operation_error.py +64 -0
  169. numdaplot/errors/refused_setting_error.py +60 -0
  170. numdaplot/errors/rejected_dates.py +60 -0
  171. numdaplot/errors/repeated_key.py +36 -0
  172. numdaplot/errors/shape_mismatch_error.py +67 -0
  173. numdaplot/errors/time_overflow_error.py +131 -0
  174. numdaplot/errors/time_zone_mismatch_error.py +83 -0
  175. numdaplot/errors/unknown_time_zone_error.py +51 -0
  176. numdaplot/errors/unmatched_value_error.py +81 -0
  177. numdaplot/errors/unsupported_image_format_error.py +56 -0
  178. numdaplot/errors/unsupported_index_error.py +38 -0
  179. numdaplot/errors/unsupported_missing_error.py +129 -0
  180. numdaplot/errors/unsupported_type_error.py +62 -0
  181. numdaplot/errors/value_conversion_error.py +215 -0
  182. numdaplot/ordering/__init__.py +5 -0
  183. numdaplot/ordering/missing_position.py +46 -0
  184. numdaplot/ordering/order.py +46 -0
  185. numdaplot/package_version.py +36 -0
  186. numdaplot/plots/__init__.py +5 -0
  187. numdaplot/plots/chart_layer.py +47 -0
  188. numdaplot/plots/charts/__init__.py +5 -0
  189. numdaplot/plots/charts/bar_chart.py +98 -0
  190. numdaplot/plots/charts/bar_layout.py +58 -0
  191. numdaplot/plots/charts/bin_count.py +61 -0
  192. numdaplot/plots/charts/bin_width.py +78 -0
  193. numdaplot/plots/charts/box_chart.py +97 -0
  194. numdaplot/plots/charts/cell_values.py +61 -0
  195. numdaplot/plots/charts/chart.py +59 -0
  196. numdaplot/plots/charts/chart_settings.py +105 -0
  197. numdaplot/plots/charts/color_scale.py +147 -0
  198. numdaplot/plots/charts/heatmap_chart.py +92 -0
  199. numdaplot/plots/charts/histogram_chart.py +93 -0
  200. numdaplot/plots/charts/line_chart.py +100 -0
  201. numdaplot/plots/charts/line_type.py +75 -0
  202. numdaplot/plots/charts/marker_shape.py +113 -0
  203. numdaplot/plots/charts/missing_chart.py +60 -0
  204. numdaplot/plots/charts/missing_map_chart.py +27 -0
  205. numdaplot/plots/charts/orientation.py +58 -0
  206. numdaplot/plots/charts/outliers.py +49 -0
  207. numdaplot/plots/charts/percentages.py +55 -0
  208. numdaplot/plots/charts/pie_chart.py +87 -0
  209. numdaplot/plots/charts/scatter_chart.py +159 -0
  210. numdaplot/plots/charts/value_axis.py +66 -0
  211. numdaplot/plots/data/__init__.py +5 -0
  212. numdaplot/plots/data/array_values.py +128 -0
  213. numdaplot/plots/data/chart_data.py +143 -0
  214. numdaplot/plots/data/chart_values.py +109 -0
  215. numdaplot/plots/data/column_reading.py +468 -0
  216. numdaplot/plots/data/heatmap_values.py +63 -0
  217. numdaplot/plots/data/missing_cells.py +165 -0
  218. numdaplot/plots/data/pie_values.py +215 -0
  219. numdaplot/plots/data/point_values.py +249 -0
  220. numdaplot/plots/data/position_kind.py +83 -0
  221. numdaplot/plots/data/renamed_layers.py +340 -0
  222. numdaplot/plots/data/sample_values.py +160 -0
  223. numdaplot/plots/data/shown_columns.py +248 -0
  224. numdaplot/plots/data/table_values.py +256 -0
  225. numdaplot/plots/data/unique_labels.py +45 -0
  226. numdaplot/plots/drawing/__init__.py +5 -0
  227. numdaplot/plots/drawing/bar_drawing.py +316 -0
  228. numdaplot/plots/drawing/box_drawing.py +344 -0
  229. numdaplot/plots/drawing/cell_merging.py +237 -0
  230. numdaplot/plots/drawing/chart_texts.py +124 -0
  231. numdaplot/plots/drawing/color_bar.py +57 -0
  232. numdaplot/plots/drawing/color_scale_values.py +120 -0
  233. numdaplot/plots/drawing/default_labels.py +41 -0
  234. numdaplot/plots/drawing/drawn_chart.py +50 -0
  235. numdaplot/plots/drawing/grid_axes.py +75 -0
  236. numdaplot/plots/drawing/heatmap_drawing.py +313 -0
  237. numdaplot/plots/drawing/histogram_drawing.py +350 -0
  238. numdaplot/plots/drawing/label_room.py +344 -0
  239. numdaplot/plots/drawing/label_thinning.py +216 -0
  240. numdaplot/plots/drawing/layer_alignment.py +319 -0
  241. numdaplot/plots/drawing/layer_colors.py +123 -0
  242. numdaplot/plots/drawing/line_drawing.py +85 -0
  243. numdaplot/plots/drawing/marker_codes.py +20 -0
  244. numdaplot/plots/drawing/missing_drawing.py +360 -0
  245. numdaplot/plots/drawing/moment_period_formatter.py +253 -0
  246. numdaplot/plots/drawing/pie_drawing.py +185 -0
  247. numdaplot/plots/drawing/plot_axes.py +38 -0
  248. numdaplot/plots/drawing/plot_drawing.py +288 -0
  249. numdaplot/plots/drawing/plot_theme.py +45 -0
  250. numdaplot/plots/drawing/position_axis.py +278 -0
  251. numdaplot/plots/drawing/scatter_drawing.py +364 -0
  252. numdaplot/plots/drawing/series_colors.py +177 -0
  253. numdaplot/plots/drawing/size_inches.py +45 -0
  254. numdaplot/plots/drawing/style_drawing.py +410 -0
  255. numdaplot/plots/drawing/text_contrast.py +44 -0
  256. numdaplot/plots/drawing/tick_rotation.py +354 -0
  257. numdaplot/plots/drawing/time_axis.py +212 -0
  258. numdaplot/plots/drawing/whole_numbers.py +72 -0
  259. numdaplot/plots/figure/__init__.py +5 -0
  260. numdaplot/plots/figure/cell.py +95 -0
  261. numdaplot/plots/figure/figure.py +256 -0
  262. numdaplot/plots/figure/figure_drawing.py +99 -0
  263. numdaplot/plots/figure/figure_style.py +60 -0
  264. numdaplot/plots/figure/layout.py +71 -0
  265. numdaplot/plots/figure/placement.py +150 -0
  266. numdaplot/plots/layer_reading.py +166 -0
  267. numdaplot/plots/output/__init__.py +5 -0
  268. numdaplot/plots/output/image_saving.py +187 -0
  269. numdaplot/plots/output/plot_display.py +181 -0
  270. numdaplot/plots/output/shown_object.py +45 -0
  271. numdaplot/plots/overlay_checks.py +245 -0
  272. numdaplot/plots/plot.py +31 -0
  273. numdaplot/plots/plot_data.py +140 -0
  274. numdaplot/plots/plot_distribution_creation.py +237 -0
  275. numdaplot/plots/plot_output.py +124 -0
  276. numdaplot/plots/plot_overlays.py +273 -0
  277. numdaplot/plots/plot_overview_creation.py +195 -0
  278. numdaplot/plots/plot_series_creation.py +213 -0
  279. numdaplot/plots/style/__init__.py +5 -0
  280. numdaplot/plots/style/axis_settings.py +60 -0
  281. numdaplot/plots/style/color.py +168 -0
  282. numdaplot/plots/style/custom_color.py +65 -0
  283. numdaplot/plots/style/grid_lines.py +49 -0
  284. numdaplot/plots/style/image_options.py +71 -0
  285. numdaplot/plots/style/legend_position.py +149 -0
  286. numdaplot/plots/style/plot_style.py +136 -0
  287. numdaplot/plots/style/size.py +70 -0
  288. numdaplot/plots/style/size_unit.py +62 -0
  289. numdaplot/positions/__init__.py +5 -0
  290. numdaplot/positions/axis.py +54 -0
  291. numdaplot/positions/index.py +51 -0
  292. numdaplot/positions/range.py +90 -0
  293. numdaplot/positions/region.py +92 -0
  294. numdaplot/py.typed +0 -0
  295. numdaplot/ratios/__init__.py +5 -0
  296. numdaplot/ratios/fraction.py +40 -0
  297. numdaplot/ratios/measure.py +48 -0
  298. numdaplot/rules/__init__.py +5 -0
  299. numdaplot/rules/between.py +78 -0
  300. numdaplot/rules/bounds.py +83 -0
  301. numdaplot/rules/case.py +48 -0
  302. numdaplot/rules/contains.py +63 -0
  303. numdaplot/rules/equal.py +43 -0
  304. numdaplot/rules/greater.py +39 -0
  305. numdaplot/rules/greater_or_equal.py +38 -0
  306. numdaplot/rules/is_in.py +67 -0
  307. numdaplot/rules/is_missing.py +25 -0
  308. numdaplot/rules/is_present.py +25 -0
  309. numdaplot/rules/less.py +39 -0
  310. numdaplot/rules/less_or_equal.py +38 -0
  311. numdaplot/rules/not_equal.py +45 -0
  312. numdaplot/rules/rule.py +62 -0
  313. numdaplot/rules/rule_values.py +44 -0
  314. numdaplot/rules/value_rule.py +110 -0
  315. numdaplot/settings/__init__.py +5 -0
  316. numdaplot/settings/argument_types.py +327 -0
  317. numdaplot/settings/field_types.py +593 -0
  318. numdaplot/statistics/__init__.py +5 -0
  319. numdaplot/statistics/count.py +71 -0
  320. numdaplot/statistics/count_distinct.py +27 -0
  321. numdaplot/statistics/counted_missing.py +46 -0
  322. numdaplot/statistics/maximum.py +27 -0
  323. numdaplot/statistics/mean.py +27 -0
  324. numdaplot/statistics/median.py +27 -0
  325. numdaplot/statistics/minimum.py +27 -0
  326. numdaplot/statistics/most_frequent.py +27 -0
  327. numdaplot/statistics/most_frequent_count.py +27 -0
  328. numdaplot/statistics/quantile.py +61 -0
  329. numdaplot/statistics/standard_deviation.py +29 -0
  330. numdaplot/statistics/statistic.py +63 -0
  331. numdaplot/statistics/sum.py +27 -0
  332. numdaplot/tables/__init__.py +5 -0
  333. numdaplot/tables/aggregation/__init__.py +5 -0
  334. numdaplot/tables/aggregation/aggregated_frame.py +189 -0
  335. numdaplot/tables/aggregation/aggregation.py +97 -0
  336. numdaplot/tables/aggregation/calculation.py +123 -0
  337. numdaplot/tables/aggregation/result_column.py +108 -0
  338. numdaplot/tables/aggregation/row_groups.py +96 -0
  339. numdaplot/tables/aggregation/statistic_name.py +122 -0
  340. numdaplot/tables/columns/__init__.py +5 -0
  341. numdaplot/tables/columns/added_column.py +89 -0
  342. numdaplot/tables/columns/boolean_conversion.py +144 -0
  343. numdaplot/tables/columns/boolean_rule.py +59 -0
  344. numdaplot/tables/columns/bracket_end.py +50 -0
  345. numdaplot/tables/columns/bracket_names.py +346 -0
  346. numdaplot/tables/columns/bracketed_column.py +179 -0
  347. numdaplot/tables/columns/brackets.py +234 -0
  348. numdaplot/tables/columns/chosen_columns.py +55 -0
  349. numdaplot/tables/columns/column_choice.py +84 -0
  350. numdaplot/tables/columns/column_mode.py +64 -0
  351. numdaplot/tables/columns/column_names.py +186 -0
  352. numdaplot/tables/columns/conversion.py +103 -0
  353. numdaplot/tables/columns/converted_column.py +669 -0
  354. numdaplot/tables/columns/date_conversion.py +526 -0
  355. numdaplot/tables/columns/date_range.py +135 -0
  356. numdaplot/tables/columns/name_change.py +67 -0
  357. numdaplot/tables/columns/new_column.py +79 -0
  358. numdaplot/tables/columns/number_conversion.py +281 -0
  359. numdaplot/tables/columns/renamed_columns.py +60 -0
  360. numdaplot/tables/columns/renaming.py +81 -0
  361. numdaplot/tables/columns/text_conversion.py +70 -0
  362. numdaplot/tables/columns/time_conversion.py +313 -0
  363. numdaplot/tables/columns/time_zone_conversion.py +128 -0
  364. numdaplot/tables/conflict.py +68 -0
  365. numdaplot/tables/description/__init__.py +5 -0
  366. numdaplot/tables/description/described_frame.py +335 -0
  367. numdaplot/tables/description/description.py +155 -0
  368. numdaplot/tables/duplicates/__init__.py +5 -0
  369. numdaplot/tables/duplicates/deduplicated_frame.py +66 -0
  370. numdaplot/tables/duplicates/deduplication.py +88 -0
  371. numdaplot/tables/duplicates/keep.py +81 -0
  372. numdaplot/tables/files/__init__.py +5 -0
  373. numdaplot/tables/files/column_names.py +60 -0
  374. numdaplot/tables/files/csv_file.py +265 -0
  375. numdaplot/tables/files/csv_read_options.py +89 -0
  376. numdaplot/tables/files/csv_separator.py +41 -0
  377. numdaplot/tables/files/csv_write_options.py +79 -0
  378. numdaplot/tables/files/decimal_count.py +42 -0
  379. numdaplot/tables/files/encoding.py +82 -0
  380. numdaplot/tables/files/excel_file.py +171 -0
  381. numdaplot/tables/files/excel_read_options.py +79 -0
  382. numdaplot/tables/files/excel_sheet.py +50 -0
  383. numdaplot/tables/files/excel_time_cells.py +146 -0
  384. numdaplot/tables/files/excel_write_options.py +63 -0
  385. numdaplot/tables/files/file_access.py +152 -0
  386. numdaplot/tables/files/file_paths.py +106 -0
  387. numdaplot/tables/files/json_decimals.py +387 -0
  388. numdaplot/tables/files/json_file.py +203 -0
  389. numdaplot/tables/files/json_layout.py +63 -0
  390. numdaplot/tables/files/json_read_options.py +64 -0
  391. numdaplot/tables/files/json_write_options.py +71 -0
  392. numdaplot/tables/files/missing_texts.py +63 -0
  393. numdaplot/tables/files/optional_package.py +42 -0
  394. numdaplot/tables/files/pandas_backend.py +11 -0
  395. numdaplot/tables/files/parquet_file.py +91 -0
  396. numdaplot/tables/files/parquet_read_options.py +56 -0
  397. numdaplot/tables/files/sas_file.py +94 -0
  398. numdaplot/tables/files/sas_read_options.py +67 -0
  399. numdaplot/tables/files/stata_file.py +83 -0
  400. numdaplot/tables/files/stata_read_options.py +56 -0
  401. numdaplot/tables/files/xpt_read_options.py +65 -0
  402. numdaplot/tables/filtering/__init__.py +5 -0
  403. numdaplot/tables/filtering/checked_frame.py +60 -0
  404. numdaplot/tables/filtering/column_mask.py +71 -0
  405. numdaplot/tables/filtering/column_match.py +62 -0
  406. numdaplot/tables/filtering/condition.py +94 -0
  407. numdaplot/tables/filtering/filter.py +74 -0
  408. numdaplot/tables/filtering/filter_mode.py +67 -0
  409. numdaplot/tables/filtering/row_mask.py +152 -0
  410. numdaplot/tables/filtering/rule_moments.py +164 -0
  411. numdaplot/tables/frames/__init__.py +5 -0
  412. numdaplot/tables/frames/array_frame.py +95 -0
  413. numdaplot/tables/frames/cleaned_names.py +132 -0
  414. numdaplot/tables/frames/column.py +15 -0
  415. numdaplot/tables/frames/column_values.py +273 -0
  416. numdaplot/tables/frames/frame_equality.py +130 -0
  417. numdaplot/tables/frames/frame_normalization.py +459 -0
  418. numdaplot/tables/frames/named_column_errors.py +85 -0
  419. numdaplot/tables/frames/pandas_decimals.py +113 -0
  420. numdaplot/tables/frames/region_positions.py +113 -0
  421. numdaplot/tables/frames/table_text.py +222 -0
  422. numdaplot/tables/frames/time_columns.py +345 -0
  423. numdaplot/tables/frames/time_range_errors.py +117 -0
  424. numdaplot/tables/frames/time_zones.py +271 -0
  425. numdaplot/tables/joining/__init__.py +5 -0
  426. numdaplot/tables/joining/join.py +110 -0
  427. numdaplot/tables/joining/join_keys.py +367 -0
  428. numdaplot/tables/joining/join_mode.py +93 -0
  429. numdaplot/tables/joining/join_relation.py +149 -0
  430. numdaplot/tables/joining/join_suffixes.py +71 -0
  431. numdaplot/tables/joining/joined_frame.py +166 -0
  432. numdaplot/tables/joining/joined_names.py +107 -0
  433. numdaplot/tables/joining/joined_rows.py +235 -0
  434. numdaplot/tables/joining/key_types.py +57 -0
  435. numdaplot/tables/joining/relation.py +78 -0
  436. numdaplot/tables/missing/__init__.py +5 -0
  437. numdaplot/tables/missing/missing_count.py +59 -0
  438. numdaplot/tables/missing/missing_counts.py +214 -0
  439. numdaplot/tables/missing/missing_drop.py +98 -0
  440. numdaplot/tables/missing/missing_mode.py +63 -0
  441. numdaplot/tables/missing/missing_ratio.py +71 -0
  442. numdaplot/tables/missing/missing_removal.py +257 -0
  443. numdaplot/tables/missing/missing_summary.py +174 -0
  444. numdaplot/tables/missing/ratio_comparison.py +70 -0
  445. numdaplot/tables/pivot/__init__.py +5 -0
  446. numdaplot/tables/pivot/pivot_table.py +104 -0
  447. numdaplot/tables/pivot/pivoted_frame.py +244 -0
  448. numdaplot/tables/preview/__init__.py +5 -0
  449. numdaplot/tables/preview/notebook_display.py +238 -0
  450. numdaplot/tables/preview/preview.py +100 -0
  451. numdaplot/tables/preview/preview_rows.py +55 -0
  452. numdaplot/tables/preview/shown_columns.py +62 -0
  453. numdaplot/tables/preview/side.py +82 -0
  454. numdaplot/tables/sorting/__init__.py +5 -0
  455. numdaplot/tables/sorting/sort_key.py +71 -0
  456. numdaplot/tables/sorting/sorted_frame.py +81 -0
  457. numdaplot/tables/sorting/sorting.py +82 -0
  458. numdaplot/tables/table.py +71 -0
  459. numdaplot/tables/table_calculation.py +172 -0
  460. numdaplot/tables/table_columns.py +214 -0
  461. numdaplot/tables/table_conversion.py +351 -0
  462. numdaplot/tables/table_data.py +321 -0
  463. numdaplot/tables/table_display.py +56 -0
  464. numdaplot/tables/table_joining.py +80 -0
  465. numdaplot/tables/table_layout.py +105 -0
  466. numdaplot/tables/table_missing.py +146 -0
  467. numdaplot/tables/table_reading.py +451 -0
  468. numdaplot/tables/table_refusals.py +295 -0
  469. numdaplot/tables/table_selection.py +163 -0
  470. numdaplot/tables/table_writing.py +269 -0
  471. numdaplot-0.1.0.dist-info/METADATA +176 -0
  472. numdaplot-0.1.0.dist-info/RECORD +474 -0
  473. numdaplot-0.1.0.dist-info/WHEEL +4 -0
  474. 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,5 @@
1
+ """
2
+ Conversion of Array values to Python values, to text, and their comparison.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
@@ -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