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,268 @@
1
+ """
2
+ Statistics locating or summing the values of an Array: sum, mean, median, deviation, quantile, min, max.
3
+
4
+ Each function ignores missing values and reduces the whole Array when ``axis`` is ``None``.
5
+
6
+ .. versionadded:: 0.1.0
7
+ """
8
+
9
+ from typing import Any, cast
10
+
11
+ import numpy
12
+ from numpy.typing import NDArray
13
+
14
+ from numdaplot.arrays.selection.missing_mask import find_missing
15
+ from numdaplot.statistics.quantile import Quantile
16
+ from numdaplot.statistics.statistic import Statistic
17
+
18
+ MISSING_AWARE_KINDS = frozenset({"f", "M", "m"})
19
+ TEXT_KIND = "T"
20
+ LOWEST_TEXT = ""
21
+ POPULATION_DEGREES_OF_FREEDOM = 0
22
+
23
+
24
+ def compute_sum(values: NDArray[Any], axis: int | None, statistic: Statistic) -> Any:
25
+ """
26
+ Return the sum of the present values.
27
+
28
+ .. versionadded:: 0.1.0
29
+
30
+ Parameters
31
+ ----------
32
+ values
33
+ The values of a number or boolean Array.
34
+ axis
35
+ The numpy axis to reduce, or ``None`` for the whole Array.
36
+ statistic
37
+ The ``Sum`` statistic.
38
+
39
+ Returns
40
+ -------
41
+ Any
42
+ A single value, or one value per reduced slice.
43
+
44
+ Examples
45
+ --------
46
+ >>> import numpy
47
+ >>> import numdaplot as ndp
48
+ >>> from numdaplot.arrays.calculation.location_statistics import compute_sum
49
+ >>> compute_sum(numpy.array([1.0, numpy.nan, 2.0]), None, ndp.Sum())
50
+ np.float64(3.0)
51
+ """
52
+ total = numpy.nansum(values, axis=axis)
53
+
54
+ return total
55
+
56
+
57
+ def compute_mean(values: NDArray[Any], axis: int | None, statistic: Statistic) -> Any:
58
+ """
59
+ Return the mean of the present values.
60
+
61
+ .. versionadded:: 0.1.0
62
+
63
+ Parameters
64
+ ----------
65
+ values
66
+ The values of a number or boolean Array, at least one present value per slice.
67
+ axis
68
+ The numpy axis to reduce, or ``None`` for the whole Array.
69
+ statistic
70
+ The ``Mean`` statistic.
71
+
72
+ Returns
73
+ -------
74
+ Any
75
+ A single value, or one value per reduced slice.
76
+
77
+ Examples
78
+ --------
79
+ >>> import numpy
80
+ >>> import numdaplot as ndp
81
+ >>> from numdaplot.arrays.calculation.location_statistics import compute_mean
82
+ >>> compute_mean(numpy.array([1.0, numpy.nan, 3.0]), None, ndp.Mean())
83
+ np.float64(2.0)
84
+ """
85
+ mean = numpy.nanmean(values, axis=axis)
86
+
87
+ return mean
88
+
89
+
90
+ def compute_median(values: NDArray[Any], axis: int | None, statistic: Statistic) -> Any:
91
+ """
92
+ Return the median of the present values.
93
+
94
+ .. versionadded:: 0.1.0
95
+
96
+ Parameters
97
+ ----------
98
+ values
99
+ The values of a number Array, at least one present value per slice.
100
+ axis
101
+ The numpy axis to reduce, or ``None`` for the whole Array.
102
+ statistic
103
+ The ``Median`` statistic.
104
+
105
+ Returns
106
+ -------
107
+ Any
108
+ A single value, or one value per reduced slice.
109
+
110
+ Examples
111
+ --------
112
+ >>> import numpy
113
+ >>> import numdaplot as ndp
114
+ >>> from numdaplot.arrays.calculation.location_statistics import compute_median
115
+ >>> compute_median(numpy.array([1, 9, 2]), None, ndp.Median())
116
+ np.float64(2.0)
117
+ """
118
+ median = numpy.nanmedian(values, axis=axis)
119
+
120
+ return median
121
+
122
+
123
+ def compute_standard_deviation(values: NDArray[Any], axis: int | None, statistic: Statistic) -> Any:
124
+ """
125
+ Return the population standard deviation of the present values, divided by their number.
126
+
127
+ .. versionadded:: 0.1.0
128
+
129
+ Parameters
130
+ ----------
131
+ values
132
+ The values of a number Array, at least one present value per slice.
133
+ axis
134
+ The numpy axis to reduce, or ``None`` for the whole Array.
135
+ statistic
136
+ The ``StandardDeviation`` statistic.
137
+
138
+ Returns
139
+ -------
140
+ Any
141
+ A single value, or one value per reduced slice.
142
+
143
+ Examples
144
+ --------
145
+ >>> import numpy
146
+ >>> import numdaplot as ndp
147
+ >>> from numdaplot.arrays.calculation.location_statistics import compute_standard_deviation
148
+ >>> compute_standard_deviation(numpy.array([2, 4]), None, ndp.StandardDeviation())
149
+ np.float64(1.0)
150
+ """
151
+ deviation = numpy.nanstd(values, axis=axis, ddof=POPULATION_DEGREES_OF_FREEDOM)
152
+
153
+ return deviation
154
+
155
+
156
+ def compute_quantile(values: NDArray[Any], axis: int | None, statistic: Statistic) -> Any:
157
+ """
158
+ Return the value below which a fraction of the present values lies.
159
+
160
+ .. versionadded:: 0.1.0
161
+
162
+ Parameters
163
+ ----------
164
+ values
165
+ The values of a number Array, at least one present value per slice.
166
+ axis
167
+ The numpy axis to reduce, or ``None`` for the whole Array.
168
+ statistic
169
+ The ``Quantile`` statistic, holding the fraction.
170
+
171
+ Returns
172
+ -------
173
+ Any
174
+ A single value, or one value per reduced slice.
175
+
176
+ Examples
177
+ --------
178
+ >>> import numpy
179
+ >>> import numdaplot as ndp
180
+ >>> from numdaplot.arrays.calculation.location_statistics import compute_quantile
181
+ >>> compute_quantile(numpy.array([0, 10]), None, ndp.Quantile(0.9))
182
+ np.float64(9.0)
183
+ """
184
+ quantile = cast(Quantile, statistic)
185
+ quantile_values = numpy.nanquantile(values, quantile.fraction, axis=axis)
186
+
187
+ return quantile_values
188
+
189
+
190
+ def compute_minimum(values: NDArray[Any], axis: int | None, statistic: Statistic) -> Any:
191
+ """
192
+ Return the lowest present value: the smallest number, the first text in alphabetical order, the earliest date.
193
+
194
+ .. versionadded:: 0.1.0
195
+
196
+ Parameters
197
+ ----------
198
+ values
199
+ The values of an Array, at least one present value per slice.
200
+ axis
201
+ The numpy axis to reduce, or ``None`` for the whole Array.
202
+ statistic
203
+ The ``Min`` statistic.
204
+
205
+ Returns
206
+ -------
207
+ Any
208
+ A single value, or one value per reduced slice.
209
+
210
+ Examples
211
+ --------
212
+ >>> import numpy
213
+ >>> import numdaplot as ndp
214
+ >>> from numdaplot.arrays.calculation.location_statistics import compute_minimum
215
+ >>> compute_minimum(numpy.array([3.0, numpy.nan, 1.0]), None, ndp.Min())
216
+ np.float64(1.0)
217
+ """
218
+ if values.dtype.kind in MISSING_AWARE_KINDS:
219
+ present_minimum = numpy.nanmin(values, axis=axis)
220
+ return present_minimum
221
+
222
+ minimum = numpy.min(values, axis=axis)
223
+
224
+ return minimum
225
+
226
+
227
+ def compute_maximum(values: NDArray[Any], axis: int | None, statistic: Statistic) -> Any:
228
+ """
229
+ Return the highest present value: the largest number, the last text in alphabetical order, the latest date.
230
+
231
+ .. versionadded:: 0.1.0
232
+
233
+ Parameters
234
+ ----------
235
+ values
236
+ The values of an Array, at least one present value per slice.
237
+ axis
238
+ The numpy axis to reduce, or ``None`` for the whole Array.
239
+ statistic
240
+ The ``Max`` statistic.
241
+
242
+ Returns
243
+ -------
244
+ Any
245
+ A single value, or one value per reduced slice.
246
+
247
+ Examples
248
+ --------
249
+ >>> import numpy
250
+ >>> import numdaplot as ndp
251
+ >>> from numdaplot.arrays.calculation.location_statistics import compute_maximum
252
+ >>> compute_maximum(numpy.array(["b", "c", "a"], dtype="T"), None, ndp.Max())
253
+ 'c'
254
+ """
255
+ if values.dtype.kind in MISSING_AWARE_KINDS:
256
+ present_maximum = numpy.nanmax(values, axis=axis)
257
+ return present_maximum
258
+
259
+ if values.dtype.kind == TEXT_KIND:
260
+ # numpy orders a missing text last. The empty text orders first, so it never wins over a present text.
261
+ missing = find_missing(values)
262
+ ordered_texts = numpy.where(missing, LOWEST_TEXT, values)
263
+ highest_text = numpy.max(ordered_texts, axis=axis)
264
+ return highest_text
265
+
266
+ maximum = numpy.max(values, axis=axis)
267
+
268
+ return maximum
@@ -0,0 +1,183 @@
1
+ """
2
+ Application of a math function to each value of 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.math_functions.absolute import Absolute
13
+ from numdaplot.arrays.math_functions.cosine import Cosine
14
+ from numdaplot.arrays.math_functions.exponential import Exponential
15
+ from numdaplot.arrays.math_functions.logarithm import Logarithm
16
+ from numdaplot.arrays.math_functions.math_function import MathFunction
17
+ from numdaplot.arrays.math_functions.round import Round
18
+ from numdaplot.arrays.math_functions.sine import Sine
19
+ from numdaplot.arrays.math_functions.square_root import SquareRoot
20
+ from numdaplot.arrays.operations.float_errors import FloatErrorWarnings
21
+ from numdaplot.arrays.operations.integer_rules import require_absolute_fits
22
+ from numdaplot.arrays.operations.type_requirements import require_family
23
+ from numdaplot.data_types.value_family import ValueFamily
24
+ from numdaplot.errors.out_of_domain_error import OutOfDomainError
25
+ from numdaplot.errors.refused_operation_error import RefusedOperationError
26
+
27
+ NUMBER_FAMILIES = frozenset({ValueFamily.NUMBER})
28
+ DOMAIN_LIMIT = 0
29
+ LOGARITHM_FUNCTIONS = {
30
+ 2.0: numpy.log2,
31
+ 10.0: numpy.log10,
32
+ }
33
+ UNKNOWN_FUNCTION_OPERATION = "The math function {function_name}"
34
+ UNKNOWN_FUNCTION_ALTERNATIVE = "a math function of numdaplot"
35
+
36
+
37
+ def apply_math_function(values: NDArray[Any], function: MathFunction) -> NDArray[Any]:
38
+ """
39
+ Return the result of a math function applied to each value.
40
+
41
+ .. versionadded:: 0.1.0
42
+
43
+ Parameters
44
+ ----------
45
+ values
46
+ The values of a number Array.
47
+ function
48
+ Any math function of numdaplot.
49
+
50
+ Returns
51
+ -------
52
+ NDArray
53
+ The transformed values. Missing values stay missing.
54
+
55
+ Raises
56
+ ------
57
+ IncompatibleTypesError
58
+ When the values are not numbers.
59
+ OutOfDomainError
60
+ When a value is outside the domain of the function.
61
+ RefusedOperationError
62
+ When the function is not a math function of numdaplot.
63
+
64
+ Examples
65
+ --------
66
+ >>> import numpy
67
+ >>> import numdaplot as ndp
68
+ >>> from numdaplot.arrays.calculation.math_function_values import apply_math_function
69
+ >>> apply_math_function(numpy.array([1, 100]), ndp.Logarithm(base=10))
70
+ array([0., 2.])
71
+ """
72
+ function_class = type(function)
73
+ function_name = function_class.__name__
74
+ require_family(values, NUMBER_FAMILIES, function_name)
75
+
76
+ with FloatErrorWarnings(function_name):
77
+ match function:
78
+ case SquareRoot():
79
+ require_domain(values, numpy.less, function_name)
80
+ transformed_values = numpy.sqrt(values)
81
+ case Logarithm():
82
+ require_domain(values, numpy.less_equal, function_name)
83
+ transformed_values = compute_logarithm(values, function)
84
+ case Exponential():
85
+ transformed_values = numpy.exp(values)
86
+ case Absolute():
87
+ require_absolute_fits(values, function_name)
88
+ transformed_values = numpy.absolute(values)
89
+ case Round():
90
+ transformed_values = numpy.round(values, function.decimals)
91
+ case Sine():
92
+ transformed_values = numpy.sin(values)
93
+ case Cosine():
94
+ transformed_values = numpy.cos(values)
95
+ case _:
96
+ operation = UNKNOWN_FUNCTION_OPERATION.format(function_name=function_name)
97
+ raise RefusedOperationError(operation, UNKNOWN_FUNCTION_ALTERNATIVE)
98
+
99
+ return transformed_values
100
+
101
+
102
+ def require_domain(values: NDArray[Any], is_outside: numpy.ufunc, function_name: str) -> None:
103
+ """
104
+ Check that no value is outside the domain of a math function, by comparison with 0.
105
+
106
+ .. versionadded:: 0.1.0
107
+
108
+ Parameters
109
+ ----------
110
+ values
111
+ The values of a number Array. Missing values are never outside.
112
+ is_outside
113
+ The comparison with 0 telling a value is outside, such as ``numpy.less`` for a square root.
114
+ function_name
115
+ Name of the math function, shown in the error message.
116
+
117
+ Raises
118
+ ------
119
+ OutOfDomainError
120
+ At the first value outside the domain.
121
+
122
+ Examples
123
+ --------
124
+ >>> import numpy
125
+ >>> import numdaplot as ndp
126
+ >>> from numdaplot.arrays.calculation.math_function_values import require_domain
127
+ >>> try:
128
+ ... require_domain(numpy.array([4, -9]), numpy.less, "SquareRoot")
129
+ ... except ndp.OutOfDomainError as error:
130
+ ... print(error)
131
+ SquareRoot is not defined for -9.
132
+ """
133
+ outside = is_outside(values, DOMAIN_LIMIT)
134
+ has_outside_value = outside.any()
135
+ if has_outside_value:
136
+ outside_values = values[outside]
137
+ first_outside_value = outside_values[0]
138
+ rejected_value = first_outside_value.item()
139
+ raise OutOfDomainError(function_name, rejected_value)
140
+
141
+
142
+ def compute_logarithm(values: NDArray[Any], logarithm: Logarithm) -> NDArray[Any]:
143
+ """
144
+ Return the logarithm of each value, in the base of a ``Logarithm``.
145
+
146
+ Bases 2 and 10 use their dedicated numpy functions, which give exact results on exact powers.
147
+
148
+ .. versionadded:: 0.1.0
149
+
150
+ Parameters
151
+ ----------
152
+ values
153
+ The values, all greater than 0 or missing.
154
+ logarithm
155
+ The base, natural when ``None``.
156
+
157
+ Returns
158
+ -------
159
+ NDArray
160
+ The logarithm of each value.
161
+
162
+ Examples
163
+ --------
164
+ >>> import numpy
165
+ >>> import numdaplot as ndp
166
+ >>> from numdaplot.arrays.calculation.math_function_values import compute_logarithm
167
+ >>> compute_logarithm(numpy.array([8]), ndp.Logarithm(base=2))
168
+ array([3.])
169
+ """
170
+ natural_logarithms = numpy.log(values)
171
+ base = logarithm.base
172
+ if base is None:
173
+ return natural_logarithms
174
+
175
+ if base in LOGARITHM_FUNCTIONS:
176
+ dedicated_function = LOGARITHM_FUNCTIONS[base]
177
+ dedicated_logarithms = dedicated_function(values)
178
+ return dedicated_logarithms
179
+
180
+ base_logarithm = numpy.log(base)
181
+ logarithms = natural_logarithms / base_logarithm
182
+
183
+ return logarithms
@@ -0,0 +1,209 @@
1
+ """
2
+ Computation of any statistic on the values of an Array.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from collections.abc import Callable
8
+ from dataclasses import dataclass
9
+ from typing import Any
10
+
11
+ import numpy
12
+ from numpy.typing import NDArray
13
+
14
+ from numdaplot.arrays.axis_number import find_numpy_axis
15
+ from numdaplot.arrays.calculation.counting_statistics import (
16
+ compute_count,
17
+ compute_count_distinct,
18
+ compute_most_frequent,
19
+ compute_most_frequent_count,
20
+ )
21
+ from numdaplot.arrays.calculation.location_statistics import (
22
+ compute_maximum,
23
+ compute_mean,
24
+ compute_median,
25
+ compute_minimum,
26
+ compute_quantile,
27
+ compute_standard_deviation,
28
+ compute_sum,
29
+ )
30
+ from numdaplot.arrays.creation.numpy_conversion import normalize_text
31
+ from numdaplot.arrays.operations.float_errors import FloatErrorWarnings
32
+ from numdaplot.arrays.operations.integer_rules import require_sum_fits
33
+ from numdaplot.arrays.operations.type_requirements import require_family
34
+ from numdaplot.arrays.selection.missing_mask import find_missing
35
+ from numdaplot.data_types.value_family import ValueFamily
36
+ from numdaplot.errors.empty_array_error import EmptyArrayError
37
+ from numdaplot.errors.refused_operation_error import RefusedOperationError
38
+ from numdaplot.positions.axis import Axis
39
+ from numdaplot.statistics.count import Count
40
+ from numdaplot.statistics.count_distinct import CountDistinct
41
+ from numdaplot.statistics.maximum import Max
42
+ from numdaplot.statistics.mean import Mean
43
+ from numdaplot.statistics.median import Median
44
+ from numdaplot.statistics.minimum import Min
45
+ from numdaplot.statistics.most_frequent import MostFrequent
46
+ from numdaplot.statistics.most_frequent_count import MostFrequentCount
47
+ from numdaplot.statistics.quantile import Quantile
48
+ from numdaplot.statistics.standard_deviation import StandardDeviation
49
+ from numdaplot.statistics.statistic import Statistic
50
+ from numdaplot.statistics.sum import Sum
51
+
52
+ type StatisticFunction = Callable[[NDArray[Any], int | None, Statistic], Any]
53
+
54
+
55
+ @dataclass(frozen=True)
56
+ class StatisticCalculation:
57
+ """
58
+ How a statistic is computed on the values of an Array.
59
+
60
+ .. versionadded:: 0.1.0
61
+
62
+ Parameters
63
+ ----------
64
+ function
65
+ The function computing the statistic, given the values, the numpy axis and the statistic.
66
+ accepted_families
67
+ The families of types the statistic applies to.
68
+ needs_present_value
69
+ Whether the statistic needs at least one present value per slice.
70
+ """
71
+
72
+ function: StatisticFunction
73
+ accepted_families: frozenset[ValueFamily]
74
+ needs_present_value: bool
75
+
76
+
77
+ ALL_FAMILIES = frozenset(ValueFamily)
78
+ NUMBER_FAMILIES = frozenset({ValueFamily.NUMBER})
79
+ NUMBER_AND_BOOL_FAMILIES = frozenset({ValueFamily.NUMBER, ValueFamily.BOOL})
80
+ STATISTIC_CALCULATIONS = {
81
+ Sum: StatisticCalculation(compute_sum, NUMBER_AND_BOOL_FAMILIES, needs_present_value=False),
82
+ Mean: StatisticCalculation(compute_mean, NUMBER_AND_BOOL_FAMILIES, needs_present_value=True),
83
+ Median: StatisticCalculation(compute_median, NUMBER_FAMILIES, needs_present_value=True),
84
+ Min: StatisticCalculation(compute_minimum, ALL_FAMILIES, needs_present_value=True),
85
+ Max: StatisticCalculation(compute_maximum, ALL_FAMILIES, needs_present_value=True),
86
+ Count: StatisticCalculation(compute_count, ALL_FAMILIES, needs_present_value=False),
87
+ CountDistinct: StatisticCalculation(compute_count_distinct, ALL_FAMILIES, needs_present_value=False),
88
+ StandardDeviation: StatisticCalculation(compute_standard_deviation, NUMBER_FAMILIES, needs_present_value=True),
89
+ Quantile: StatisticCalculation(compute_quantile, NUMBER_FAMILIES, needs_present_value=True),
90
+ MostFrequent: StatisticCalculation(compute_most_frequent, ALL_FAMILIES, needs_present_value=True),
91
+ MostFrequentCount: StatisticCalculation(compute_most_frequent_count, ALL_FAMILIES, needs_present_value=False),
92
+ }
93
+ SINGLE_VALUE_DIMENSIONS = (1,)
94
+ UNKNOWN_STATISTIC_OPERATION = "The statistic {statistic_name}"
95
+ UNKNOWN_STATISTIC_ALTERNATIVE = "a statistic of numdaplot"
96
+
97
+
98
+ def compute_statistic(values: NDArray[Any], statistic: Statistic, axis: Axis | None) -> NDArray[Any]:
99
+ """
100
+ Return a statistic of the present values, for the whole Array or for each row or column.
101
+
102
+ .. versionadded:: 0.1.0
103
+
104
+ Parameters
105
+ ----------
106
+ values
107
+ The values of an Array.
108
+ statistic
109
+ Any statistic of numdaplot.
110
+ axis
111
+ ``EACH_ROW`` for one result per row, ``EACH_COLUMN`` for one per column,
112
+ ``None`` for a single result.
113
+
114
+ Returns
115
+ -------
116
+ NDArray
117
+ A single value in one dimension when ``axis`` is ``None``, otherwise one value per row or column.
118
+
119
+ Raises
120
+ ------
121
+ IncompatibleTypesError
122
+ When the statistic does not apply to the type of the values.
123
+ DimensionError
124
+ When an axis is given for an Array that is not two-dimensional.
125
+ EmptyArrayError
126
+ When the statistic needs a present value and a slice has none.
127
+ RefusedOperationError
128
+ When the statistic is not a statistic of numdaplot.
129
+ IntegerOverflowError
130
+ When the sum of integers does not fit their type.
131
+
132
+ Warns
133
+ -----
134
+ CalculationWarning
135
+ When a result on decimals becomes NaN or an infinite value.
136
+
137
+ Examples
138
+ --------
139
+ >>> import numpy
140
+ >>> import numdaplot as ndp
141
+ >>> from numdaplot.arrays.calculation.statistic_values import compute_statistic
142
+ >>> compute_statistic(numpy.array([[1, 2], [3, 4]]), ndp.Sum(), ndp.Axis.EACH_ROW)
143
+ array([3, 7])
144
+ """
145
+ statistic_class = type(statistic)
146
+ statistic_name = statistic_class.__name__
147
+ if statistic_class not in STATISTIC_CALCULATIONS:
148
+ operation = UNKNOWN_STATISTIC_OPERATION.format(statistic_name=statistic_name)
149
+ raise RefusedOperationError(operation, UNKNOWN_STATISTIC_ALTERNATIVE)
150
+
151
+ calculation = STATISTIC_CALCULATIONS[statistic_class]
152
+ require_family(values, calculation.accepted_families, statistic_name)
153
+ numpy_axis = find_numpy_axis(axis, values.ndim)
154
+ if calculation.needs_present_value:
155
+ require_present_values(values, numpy_axis, statistic_name)
156
+
157
+ with FloatErrorWarnings(statistic_name):
158
+ result = calculation.function(values, numpy_axis, statistic)
159
+
160
+ result_values = numpy.asarray(result)
161
+ if statistic_class == Sum:
162
+ require_sum_fits(values, numpy_axis, result_values, statistic_name)
163
+
164
+ if numpy_axis is None:
165
+ result_values = result_values.reshape(SINGLE_VALUE_DIMENSIONS)
166
+
167
+ normalized_values = normalize_text(result_values)
168
+
169
+ return normalized_values
170
+
171
+
172
+ def require_present_values(values: NDArray[Any], axis: int | None, statistic_name: str) -> None:
173
+ """
174
+ Check that the whole Array, or each slice along an axis, holds at least one present value.
175
+
176
+ .. versionadded:: 0.1.0
177
+
178
+ Parameters
179
+ ----------
180
+ values
181
+ The values of an Array.
182
+ axis
183
+ The numpy axis to reduce, or ``None`` for the whole Array.
184
+ statistic_name
185
+ Name of the statistic, shown in the error message.
186
+
187
+ Raises
188
+ ------
189
+ EmptyArrayError
190
+ When the Array, or one of its slices, has no present value.
191
+
192
+ Examples
193
+ --------
194
+ >>> import numpy
195
+ >>> import numdaplot as ndp
196
+ >>> from numdaplot.arrays.calculation.statistic_values import require_present_values
197
+ >>> try:
198
+ ... require_present_values(numpy.array([numpy.nan]), None, "Mean")
199
+ ... except ndp.EmptyArrayError as error:
200
+ ... print(error)
201
+ Cannot compute Mean without any present value.
202
+ """
203
+ missing = find_missing(values)
204
+ present = ~missing
205
+ present_counts = numpy.sum(present, axis=axis)
206
+ empty_slices = present_counts == 0
207
+ has_empty_slice = numpy.any(empty_slices)
208
+ if has_empty_slice:
209
+ raise EmptyArrayError(statistic_name)