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,593 @@
1
+ """
2
+ Check of the settings of an object against the annotations of its fields.
3
+
4
+ The annotations are the only description of what a setting accepts, so a check and a signature never disagree.
5
+
6
+ .. versionadded:: 0.1.0
7
+ """
8
+
9
+ import dataclasses
10
+ import functools
11
+ import importlib
12
+ import types
13
+ import typing
14
+ from collections.abc import Sequence
15
+ from dataclasses import dataclass
16
+ from typing import Any, cast
17
+
18
+ import numpy
19
+
20
+ from numdaplot.errors.invalid_type_error import InvalidTypeError
21
+
22
+ PACKAGE_NAME = "numdaplot"
23
+ NONE_NAME = "None"
24
+ VOWELS = "aeiouAEIOU"
25
+ # These words start with a vowel letter but with a consonant sound, as in "a Uniform".
26
+ CONSONANT_SOUND_PREFIXES = ("Uni",)
27
+ ARTICLE_FORMAT = "{article} {name}"
28
+ NAMES_SEPARATOR = ", "
29
+ LAST_NAME_FORMAT = "{names} or {last_name}"
30
+ LIST_OF_FORMAT = "a list of {names}"
31
+ ANY_LIST = "a list"
32
+ LIST_SUCH_AS_FORMAT = "a list such as [{text!r}]"
33
+ SETTING_NAME_FORMAT = "{owner_name} {field_name}"
34
+ NUMBER_CLASSES = dict[object, tuple[type, ...]](
35
+ {
36
+ bool: (bool, numpy.bool_),
37
+ int: (int, numpy.integer),
38
+ float: (int, float, numpy.integer, numpy.floating),
39
+ }
40
+ )
41
+ UNION_ORIGINS = (typing.Union, types.UnionType)
42
+ LIST_ORIGINS = (list, Sequence)
43
+
44
+
45
+ @dataclass(frozen=True)
46
+ class AcceptedKinds:
47
+ """
48
+ What a setting accepts, read from its annotation.
49
+
50
+ .. versionadded:: 0.1.0
51
+
52
+ Parameters
53
+ ----------
54
+ classes
55
+ The accepted classes.
56
+ list_items
57
+ What the items of a list accept, or None when a list is not accepted.
58
+ names
59
+ The names of the accepted classes, in the order of the annotation, a list being left out.
60
+ """
61
+
62
+ classes: tuple[type, ...]
63
+ list_items: "AcceptedKinds | None"
64
+ names: tuple[str, ...]
65
+
66
+
67
+ @dataclass(frozen=True)
68
+ class FieldCheck:
69
+ """
70
+ One field of a setting object, and what it accepts.
71
+
72
+ .. versionadded:: 0.1.0
73
+
74
+ Parameters
75
+ ----------
76
+ field_name
77
+ The name of the field.
78
+ setting_name
79
+ The name shown in the error message, such as ``"Region rows"``.
80
+ kinds
81
+ What the field accepts.
82
+ """
83
+
84
+ field_name: str
85
+ setting_name: str
86
+ kinds: AcceptedKinds
87
+
88
+
89
+ def require_field_types(setting: object) -> None:
90
+ """
91
+ Check that every field of a setting object holds a value accepted by its annotation.
92
+
93
+ .. versionadded:: 0.1.0
94
+
95
+ Parameters
96
+ ----------
97
+ setting
98
+ The dataclass instance to check.
99
+
100
+ Raises
101
+ ------
102
+ InvalidTypeError
103
+ At the first field holding a value its annotation does not accept.
104
+
105
+ Examples
106
+ --------
107
+ >>> import numdaplot as ndp
108
+ >>> from numdaplot.settings.field_types import require_field_types
109
+ >>> require_field_types(ndp.Index(1))
110
+ >>> try:
111
+ ... ndp.Preview(count="2")
112
+ ... except ndp.InvalidTypeError as error:
113
+ ... print(error)
114
+ Preview count expects an int, got '2'.
115
+ """
116
+ setting_class = type(setting)
117
+ field_checks = find_field_checks(setting_class)
118
+
119
+ for field_check in field_checks:
120
+ value = getattr(setting, field_check.field_name)
121
+ is_accepted = accepts_value(field_check.kinds, value)
122
+ if not is_accepted:
123
+ expected = describe_kinds(field_check.kinds, value)
124
+ rejected_value = find_rejected_value(field_check.kinds, value)
125
+ raise InvalidTypeError(field_check.setting_name, expected, rejected_value)
126
+
127
+
128
+ @functools.cache
129
+ def find_field_checks(setting_class: type) -> tuple[FieldCheck, ...]:
130
+ """
131
+ Return the checks of the fields of a dataclass, built once for each class.
132
+
133
+ .. versionadded:: 0.1.0
134
+
135
+ Parameters
136
+ ----------
137
+ setting_class
138
+ The dataclass.
139
+
140
+ Returns
141
+ -------
142
+ tuple[FieldCheck, ...]
143
+ One check per field.
144
+
145
+ Examples
146
+ --------
147
+ >>> import numdaplot as ndp
148
+ >>> from numdaplot.settings.field_types import find_field_checks
149
+ >>> find_field_checks(ndp.Index)[0].setting_name
150
+ 'Index position'
151
+ """
152
+ annotations = read_annotations(setting_class)
153
+ field_checks = list[FieldCheck]()
154
+ dataclass_fields = dataclasses.fields(setting_class)
155
+
156
+ for dataclass_field in dataclass_fields:
157
+ field_name = dataclass_field.name
158
+ setting_name = SETTING_NAME_FORMAT.format(owner_name=setting_class.__name__, field_name=field_name)
159
+ kinds = read_accepted_kinds(annotations[field_name])
160
+ field_check = FieldCheck(field_name, setting_name, kinds)
161
+ field_checks.append(field_check)
162
+
163
+ return tuple(field_checks)
164
+
165
+
166
+ def read_annotations(annotated: Any) -> dict[str, Any]:
167
+ """
168
+ Return the annotations of a class or a function, resolving the names only known to the type checker.
169
+
170
+ Array and its settings refer to each other, so some annotations are texts naming a class that their module
171
+ cannot import. Those names are looked up in numdaplot at the first call, when it is entirely imported.
172
+
173
+ .. versionadded:: 0.1.0
174
+
175
+ Parameters
176
+ ----------
177
+ annotated
178
+ The class or the function.
179
+
180
+ Returns
181
+ -------
182
+ dict[str, Any]
183
+ The annotation of each field or parameter.
184
+
185
+ Examples
186
+ --------
187
+ >>> import numdaplot as ndp
188
+ >>> from numdaplot.settings.field_types import read_annotations
189
+ >>> read_annotations(ndp.Index)["position"]
190
+ <class 'int'>
191
+ """
192
+ try:
193
+ annotations = typing.get_type_hints(annotated)
194
+ except NameError:
195
+ package = importlib.import_module(PACKAGE_NAME)
196
+ package_names = vars(package)
197
+ annotations = typing.get_type_hints(annotated, localns=package_names)
198
+
199
+ return annotations
200
+
201
+
202
+ def read_accepted_kinds(annotation: object, open_aliases: frozenset[object] = frozenset()) -> AcceptedKinds:
203
+ """
204
+ Return what an annotation accepts, going through its aliases, its type parameters and its unions.
205
+
206
+ .. versionadded:: 0.1.0
207
+
208
+ Parameters
209
+ ----------
210
+ annotation
211
+ The annotation of a field.
212
+ open_aliases
213
+ The aliases being expanded, none by default.
214
+
215
+ Returns
216
+ -------
217
+ AcceptedKinds
218
+ The accepted classes, and what the items of a list accept.
219
+
220
+ Examples
221
+ --------
222
+ >>> import numdaplot as ndp
223
+ >>> from numdaplot.settings.field_types import read_accepted_kinds
224
+ >>> read_accepted_kinds(ndp.Side | None).names
225
+ ('Side', 'None')
226
+ """
227
+ classes = list[type]()
228
+ names = list[str]()
229
+ list_items = None
230
+ expanded_aliases = open_aliases
231
+ if isinstance(annotation, typing.TypeAliasType):
232
+ expanded_aliases = open_aliases | {annotation}
233
+
234
+ members = list_annotation_members(annotation, open_aliases)
235
+
236
+ for member in members:
237
+ origin = typing.get_origin(member)
238
+ if origin in LIST_ORIGINS:
239
+ item_annotation = typing.get_args(member)[0]
240
+ list_items = read_accepted_kinds(item_annotation, expanded_aliases)
241
+ continue
242
+
243
+ member_classes = find_member_classes(member)
244
+ classes.extend(member_classes)
245
+ member_name = find_member_name(member)
246
+ names.append(member_name)
247
+
248
+ return AcceptedKinds(tuple(classes), list_items, tuple(names))
249
+
250
+
251
+ def list_annotation_members(annotation: object, open_aliases: frozenset[object] = frozenset()) -> list[object]:
252
+ """
253
+ Return the members of an annotation, with its aliases, its type parameters and its unions expanded.
254
+
255
+ .. versionadded:: 0.1.0
256
+
257
+ Parameters
258
+ ----------
259
+ annotation
260
+ The annotation.
261
+ open_aliases
262
+ The aliases being expanded, none by default.
263
+
264
+ Returns
265
+ -------
266
+ list[object]
267
+ The classes and the list annotations it accepts.
268
+
269
+ Examples
270
+ --------
271
+ >>> from numdaplot.settings.field_types import list_annotation_members
272
+ >>> list_annotation_members(int | None)
273
+ [<class 'int'>, <class 'NoneType'>]
274
+ """
275
+ if isinstance(annotation, typing.TypeAliasType):
276
+ # An alias naming itself, such as nested lists, accepts anything at its deeper levels.
277
+ if annotation in open_aliases:
278
+ return [typing.Any]
279
+
280
+ aliased_members = list_annotation_members(annotation.__value__, open_aliases | {annotation})
281
+ return aliased_members
282
+
283
+ nested_annotations = None
284
+ if isinstance(annotation, typing.TypeVar):
285
+ # A type parameter without constraint accepts anything.
286
+ nested_annotations = annotation.__constraints__ or (typing.Any,)
287
+
288
+ origin = typing.get_origin(annotation)
289
+ if isinstance(origin, typing.TypeAliasType):
290
+ nested_annotations = (origin.__value__,)
291
+
292
+ if origin in UNION_ORIGINS:
293
+ nested_annotations = typing.get_args(annotation)
294
+
295
+ if nested_annotations is None:
296
+ return [annotation]
297
+
298
+ members = list[object]()
299
+
300
+ for nested_annotation in nested_annotations:
301
+ nested_members = list_annotation_members(nested_annotation, open_aliases)
302
+ members.extend(nested_members)
303
+
304
+ return members
305
+
306
+
307
+ def find_member_classes(member: object) -> tuple[type, ...]:
308
+ """
309
+ Return the classes a member of an annotation accepts: numbers from numpy count as Python numbers.
310
+
311
+ .. versionadded:: 0.1.0
312
+
313
+ Parameters
314
+ ----------
315
+ member
316
+ A class, or ``typing.Any`` which accepts everything.
317
+
318
+ Returns
319
+ -------
320
+ tuple[type, ...]
321
+ The accepted classes.
322
+
323
+ Examples
324
+ --------
325
+ >>> from numdaplot.settings.field_types import find_member_classes
326
+ >>> find_member_classes(str)
327
+ (<class 'str'>,)
328
+ """
329
+ if member is typing.Any:
330
+ return (object,)
331
+
332
+ if member in NUMBER_CLASSES:
333
+ return NUMBER_CLASSES[member]
334
+
335
+ origin = typing.get_origin(member)
336
+ if origin is not None:
337
+ return (cast(type, origin),)
338
+
339
+ return (cast(type, member),)
340
+
341
+
342
+ def find_member_name(member: object) -> str:
343
+ """
344
+ Return the name of a member of an annotation, as shown in the error message.
345
+
346
+ .. versionadded:: 0.1.0
347
+
348
+ Parameters
349
+ ----------
350
+ member
351
+ A class, or ``typing.Any``.
352
+
353
+ Returns
354
+ -------
355
+ str
356
+ The name of the class, ``None`` for the type of None.
357
+
358
+ Examples
359
+ --------
360
+ >>> from numdaplot.settings.field_types import find_member_name
361
+ >>> find_member_name(type(None))
362
+ 'None'
363
+ """
364
+ if member is types.NoneType:
365
+ return NONE_NAME
366
+
367
+ origin = typing.get_origin(member)
368
+ named_member = member if origin is None else origin
369
+ member_name = getattr(named_member, "__name__", str(named_member))
370
+
371
+ return member_name
372
+
373
+
374
+ def accepts_value(kinds: AcceptedKinds, value: object) -> bool:
375
+ """
376
+ Return whether a value is of an accepted kind, every item of a list included.
377
+
378
+ A boolean is a Python integer, yet it is only accepted where the annotation names ``bool``.
379
+
380
+ .. versionadded:: 0.1.0
381
+
382
+ Parameters
383
+ ----------
384
+ kinds
385
+ What the setting accepts.
386
+ value
387
+ The value.
388
+
389
+ Returns
390
+ -------
391
+ bool
392
+ True when the value is accepted.
393
+
394
+ Examples
395
+ --------
396
+ >>> from numdaplot.settings.field_types import accepts_value, read_accepted_kinds
397
+ >>> accepts_value(read_accepted_kinds(int), True)
398
+ False
399
+ >>> accepts_value(read_accepted_kinds(list[str]), ["a", 1])
400
+ False
401
+ """
402
+ if object in kinds.classes:
403
+ return True
404
+
405
+ if isinstance(value, bool):
406
+ return bool in kinds.classes
407
+
408
+ if isinstance(value, kinds.classes):
409
+ return True
410
+
411
+ if kinds.list_items is None or not isinstance(value, list):
412
+ return False
413
+
414
+ items = cast(list[object], value)
415
+
416
+ for item in items:
417
+ is_item_accepted = accepts_value(kinds.list_items, item)
418
+ if not is_item_accepted:
419
+ return False
420
+
421
+ return True
422
+
423
+
424
+ def find_rejected_value(kinds: AcceptedKinds, value: object) -> object:
425
+ """
426
+ Return what to show in the error message: the first rejected item of a list, or the rejected value.
427
+
428
+ .. versionadded:: 0.1.0
429
+
430
+ Parameters
431
+ ----------
432
+ kinds
433
+ What the setting accepts.
434
+ value
435
+ The rejected value.
436
+
437
+ Returns
438
+ -------
439
+ object
440
+ The first rejected item when the value is a list of accepted kind, the value otherwise.
441
+
442
+ Examples
443
+ --------
444
+ >>> from numdaplot.settings.field_types import find_rejected_value, read_accepted_kinds
445
+ >>> find_rejected_value(read_accepted_kinds(list[str]), ["a", 1])
446
+ 1
447
+ """
448
+ if kinds.list_items is None or not isinstance(value, list):
449
+ return value
450
+
451
+ items = cast(list[object], value)
452
+
453
+ for item in items:
454
+ is_item_accepted = accepts_value(kinds.list_items, item)
455
+ if not is_item_accepted:
456
+ return item
457
+
458
+ return items
459
+
460
+
461
+ def describe_kinds(kinds: AcceptedKinds, value: object) -> str:
462
+ """
463
+ Return what a setting accepts, as written in the error message.
464
+
465
+ A text given in place of a list is shown inside a list, the most likely thing to write.
466
+
467
+ .. versionadded:: 0.1.0
468
+
469
+ Parameters
470
+ ----------
471
+ kinds
472
+ What the setting accepts.
473
+ value
474
+ The rejected value.
475
+
476
+ Returns
477
+ -------
478
+ str
479
+ The description, such as ``an Index, a Range or None``.
480
+
481
+ Examples
482
+ --------
483
+ >>> from numdaplot.settings.field_types import describe_kinds, read_accepted_kinds
484
+ >>> describe_kinds(read_accepted_kinds(list[str]), "price")
485
+ "a list such as ['price']"
486
+ >>> describe_kinds(read_accepted_kinds(int | None), "2")
487
+ 'an int or None'
488
+ """
489
+ if kinds.list_items is not None and isinstance(value, str):
490
+ return LIST_SUCH_AS_FORMAT.format(text=value)
491
+
492
+ descriptions = [add_article(name) for name in kinds.names]
493
+ if kinds.list_items is not None:
494
+ list_description = describe_list(kinds.list_items)
495
+ descriptions.append(list_description)
496
+
497
+ description = join_names(descriptions)
498
+
499
+ return description
500
+
501
+
502
+ def describe_list(list_items: AcceptedKinds) -> str:
503
+ """
504
+ Return what a list accepts, as written in the error message.
505
+
506
+ .. versionadded:: 0.1.0
507
+
508
+ Parameters
509
+ ----------
510
+ list_items
511
+ What the items of the list accept.
512
+
513
+ Returns
514
+ -------
515
+ str
516
+ ``a list of str``, or ``a list`` when its items accept anything.
517
+
518
+ Examples
519
+ --------
520
+ >>> from typing import Any
521
+ >>> from numdaplot.settings.field_types import describe_list, read_accepted_kinds
522
+ >>> describe_list(read_accepted_kinds(str)), describe_list(read_accepted_kinds(Any))
523
+ ('a list of str', 'a list')
524
+ """
525
+ if object in list_items.classes:
526
+ return ANY_LIST
527
+
528
+ item_names = join_names(list_items.names)
529
+
530
+ return LIST_OF_FORMAT.format(names=item_names)
531
+
532
+
533
+ def add_article(name: str) -> str:
534
+ """
535
+ Return the name of a class with its article, None staying as it is.
536
+
537
+ .. versionadded:: 0.1.0
538
+
539
+ Parameters
540
+ ----------
541
+ name
542
+ The name of a class.
543
+
544
+ Returns
545
+ -------
546
+ str
547
+ The name with ``a`` or ``an``.
548
+
549
+ Examples
550
+ --------
551
+ >>> from numdaplot.settings.field_types import add_article
552
+ >>> add_article("Index"), add_article("Range"), add_article("None")
553
+ ('an Index', 'a Range', 'None')
554
+ """
555
+ if name == NONE_NAME:
556
+ return name
557
+
558
+ starts_with_vowel_sound = name[0] in VOWELS and not name.startswith(CONSONANT_SOUND_PREFIXES)
559
+ article = "an" if starts_with_vowel_sound else "a"
560
+
561
+ return ARTICLE_FORMAT.format(article=article, name=name)
562
+
563
+
564
+ def join_names(names: Sequence[str]) -> str:
565
+ """
566
+ Return names separated by commas, the last one after ``or``.
567
+
568
+ .. versionadded:: 0.1.0
569
+
570
+ Parameters
571
+ ----------
572
+ names
573
+ The names, at least one.
574
+
575
+ Returns
576
+ -------
577
+ str
578
+ The joined names.
579
+
580
+ Examples
581
+ --------
582
+ >>> from numdaplot.settings.field_types import join_names
583
+ >>> join_names(["an Index", "a Range", "None"])
584
+ 'an Index, a Range or None'
585
+ """
586
+ first_names = names[:-1]
587
+ last_name = names[-1]
588
+ if not first_names:
589
+ return last_name
590
+
591
+ joined_names = NAMES_SEPARATOR.join(first_names)
592
+
593
+ return LAST_NAME_FORMAT.format(names=joined_names, last_name=last_name)
@@ -0,0 +1,5 @@
1
+ """
2
+ Statistics computed on a set of values: shared by ``aggregate``, ``compute`` and ``describe``.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
@@ -0,0 +1,71 @@
1
+ """
2
+ Number of values statistic.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from numdaplot.settings.field_types import require_field_types
10
+ from numdaplot.statistics.counted_missing import CountedMissing
11
+ from numdaplot.statistics.statistic import Statistic
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class Count(Statistic):
16
+ """
17
+ Number of values, without the missing ones by default.
18
+
19
+ With ``CountedMissing.INCLUDED``, it gives the number of rows of each group of an aggregation, whatever the
20
+ column it is computed on. Use ``count_missing`` to count only the missing values.
21
+
22
+ .. versionadded:: 0.1.0
23
+
24
+ Parameters
25
+ ----------
26
+ missing
27
+ ``CountedMissing.EXCLUDED`` by default to count only the present values, ``CountedMissing.INCLUDED`` to count
28
+ every value.
29
+
30
+ Raises
31
+ ------
32
+ InvalidTypeError
33
+ When a setting is not of the type its annotation names.
34
+
35
+ Examples
36
+ --------
37
+ >>> import numdaplot as ndp
38
+ >>> answers = ndp.Array.from_list([4.0, None, 2.0])
39
+ >>> answers.compute(ndp.Count()).to_value()
40
+ 2
41
+ >>> answers.compute(ndp.Count(missing=ndp.CountedMissing.INCLUDED)).to_value()
42
+ 3
43
+
44
+ The number of rows of each group does not depend on the missing values of the column.
45
+
46
+ >>> colors = ndp.Array.from_list(["green", "green", "yellow"])
47
+ >>> fares = ndp.Array.from_list([7.0, None, 9.0])
48
+ >>> trips = ndp.Table.from_arrays({"color": colors, "fare": fares})
49
+ >>> every_row = ndp.Count(missing=ndp.CountedMissing.INCLUDED)
50
+ >>> trip_count = ndp.Calculation(column="fare", function=every_row, result_name="trip_count")
51
+ >>> trips.aggregate(ndp.Aggregation(calculations=[trip_count], group_by=["color"]))
52
+ color trip_count
53
+ TEXT INT64
54
+ 0 green 2
55
+ 1 yellow 1
56
+ """
57
+
58
+ missing: CountedMissing = CountedMissing.EXCLUDED
59
+
60
+ def __post_init__(self) -> None:
61
+ """
62
+ Check the type of the setting.
63
+
64
+ .. versionadded:: 0.1.0
65
+
66
+ Raises
67
+ ------
68
+ InvalidTypeError
69
+ When a setting is not of the type its annotation names.
70
+ """
71
+ require_field_types(self)
@@ -0,0 +1,27 @@
1
+ """
2
+ Number of distinct values that are not missing statistic.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from numdaplot.statistics.statistic import Statistic
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class CountDistinct(Statistic):
14
+ """
15
+ Number of distinct values that are not missing.
16
+
17
+ ``[1, 1, 2]`` gives 2.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Examples
22
+ --------
23
+ >>> import numdaplot as ndp
24
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
25
+ >>> cities.compute(ndp.CountDistinct()).to_value()
26
+ 2
27
+ """