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,46 @@
1
+ """
2
+ Whether Count counts the missing values.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from enum import Enum, auto
8
+
9
+
10
+ class CountedMissing(Enum):
11
+ """
12
+ Whether ``Count`` counts the missing values.
13
+
14
+ .. versionadded:: 0.1.0
15
+
16
+ Examples
17
+ --------
18
+ >>> import numdaplot as ndp
19
+ >>> answers = ndp.Array.from_list([4.0, None, 2.0])
20
+ >>> answers.compute(ndp.Count(missing=ndp.CountedMissing.INCLUDED)).to_value()
21
+ 3
22
+ """
23
+
24
+ EXCLUDED = auto()
25
+ """
26
+ Only the present values are counted. Default value.
27
+
28
+ Examples
29
+ --------
30
+ >>> import numdaplot as ndp
31
+ >>> answers = ndp.Array.from_list([4.0, None, 2.0])
32
+ >>> answers.compute(ndp.Count(missing=ndp.CountedMissing.EXCLUDED)).to_value()
33
+ 2
34
+ """
35
+
36
+ INCLUDED = auto()
37
+ """
38
+ Every value is counted, missing or not, which gives the number of rows of a column.
39
+
40
+ Examples
41
+ --------
42
+ >>> import numdaplot as ndp
43
+ >>> answers = ndp.Array.from_list([4.0, None, 2.0])
44
+ >>> answers.compute(ndp.Count(missing=ndp.CountedMissing.INCLUDED)).to_value()
45
+ 3
46
+ """
@@ -0,0 +1,27 @@
1
+ """
2
+ Largest value 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 Max(Statistic):
14
+ """
15
+ Largest value.
16
+
17
+ Missing values are ignored.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Examples
22
+ --------
23
+ >>> import numdaplot as ndp
24
+ >>> prices = ndp.Array.from_list([12.0, None, 30.0])
25
+ >>> prices.compute(ndp.Max()).to_value()
26
+ 30.0
27
+ """
@@ -0,0 +1,27 @@
1
+ """
2
+ Arithmetic mean of the values 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 Mean(Statistic):
14
+ """
15
+ Arithmetic mean of the values.
16
+
17
+ Missing values are ignored.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Examples
22
+ --------
23
+ >>> import numdaplot as ndp
24
+ >>> prices = ndp.Array.from_list([10.0, None, 30.0])
25
+ >>> prices.compute(ndp.Mean()).to_value()
26
+ 20.0
27
+ """
@@ -0,0 +1,27 @@
1
+ """
2
+ Median of the values, the middle value once sorted 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 Median(Statistic):
14
+ """
15
+ Median of the values, the middle value once sorted.
16
+
17
+ It equals ``Quantile(0.5)``. Missing values are ignored.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Examples
22
+ --------
23
+ >>> import numdaplot as ndp
24
+ >>> salaries = ndp.Array.from_list([1800, 2000, 9000])
25
+ >>> salaries.compute(ndp.Median()).to_value()
26
+ 2000.0
27
+ """
@@ -0,0 +1,27 @@
1
+ """
2
+ Smallest value 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 Min(Statistic):
14
+ """
15
+ Smallest value.
16
+
17
+ Missing values are ignored.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Examples
22
+ --------
23
+ >>> import numdaplot as ndp
24
+ >>> cities = ndp.Array.from_list(["Pau", "Lyon", "Paris"])
25
+ >>> cities.compute(ndp.Min()).to_value()
26
+ 'Lyon'
27
+ """
@@ -0,0 +1,27 @@
1
+ """
2
+ Value that appears the most often 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 MostFrequent(Statistic):
14
+ """
15
+ Value that appears the most often.
16
+
17
+ Works on any type, text included. Missing values are ignored.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Examples
22
+ --------
23
+ >>> import numdaplot as ndp
24
+ >>> sizes = ndp.Array.from_list(["M", "L", "M"])
25
+ >>> sizes.compute(ndp.MostFrequent()).to_value()
26
+ 'M'
27
+ """
@@ -0,0 +1,27 @@
1
+ """
2
+ Number of times the most frequent value appears 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 MostFrequentCount(Statistic):
14
+ """
15
+ Number of times the most frequent value appears.
16
+
17
+ Works on any type, text included.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Examples
22
+ --------
23
+ >>> import numdaplot as ndp
24
+ >>> sizes = ndp.Array.from_list(["M", "L", "M"])
25
+ >>> sizes.compute(ndp.MostFrequentCount()).to_value()
26
+ 2
27
+ """
@@ -0,0 +1,61 @@
1
+ """
2
+ Quantile statistic.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from numdaplot.ratios.fraction import require_fraction
10
+ from numdaplot.settings.field_types import require_field_types
11
+ from numdaplot.statistics.statistic import Statistic
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class Quantile(Statistic):
16
+ """
17
+ Value below which a given fraction of the values lies.
18
+
19
+ ``Quantile(0.9)`` on salaries gives the salary below which 90 % of people are,
20
+ and ``Quantile(0.5)`` is the median. Missing values are ignored.
21
+
22
+ .. versionadded:: 0.1.0
23
+
24
+ Parameters
25
+ ----------
26
+ fraction
27
+ Fraction of the values that lie below the result, between 0 and 1 included.
28
+
29
+ Raises
30
+ ------
31
+ InvalidTypeError
32
+ When a setting is not of the type its annotation names.
33
+ InvalidFractionError
34
+ When ``fraction`` is lower than 0, greater than 1 or NaN.
35
+
36
+ Examples
37
+ --------
38
+ >>> import numdaplot as ndp
39
+ >>> salaries = ndp.Array.from_list([1000, 2000, 3000, 4000, 5000])
40
+ >>> salaries.compute(ndp.Quantile(0.9)).to_value()
41
+ 4600.0
42
+ """
43
+
44
+ fraction: float
45
+
46
+ def __post_init__(self) -> None:
47
+ """
48
+ Check that the fraction is between 0 and 1.
49
+
50
+ .. versionadded:: 0.1.0
51
+
52
+ Raises
53
+ ------
54
+ InvalidTypeError
55
+ When a setting is not of the type its annotation names.
56
+ InvalidFractionError
57
+ When ``fraction`` is lower than 0, greater than 1 or NaN.
58
+ """
59
+ require_field_types(self)
60
+
61
+ require_fraction(self.fraction)
@@ -0,0 +1,29 @@
1
+ """
2
+ Standard deviation 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 StandardDeviation(Statistic):
14
+ """
15
+ Standard deviation of the values, how far they spread around the mean.
16
+
17
+ ``[10, 10, 10]`` gives 0, while ``[0, 10, 20]`` gives about 8.2. It is the population standard
18
+ deviation, divided by the number of values as in numpy, not by that number minus one as in pandas.
19
+ Missing values are ignored.
20
+
21
+ .. versionadded:: 0.1.0
22
+
23
+ Examples
24
+ --------
25
+ >>> import numdaplot as ndp
26
+ >>> grades = ndp.Array.from_list([8, 12])
27
+ >>> grades.compute(ndp.StandardDeviation()).to_value()
28
+ 2.0
29
+ """
@@ -0,0 +1,63 @@
1
+ """
2
+ Base class of every statistic.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from numdaplot.errors.refused_operation_error import RefusedOperationError
8
+
9
+ CONSTRUCTOR_OPERATION = "Creating a Statistic with ndp.Statistic()"
10
+ CONSTRUCTOR_ALTERNATIVE = "a statistic such as ndp.Mean"
11
+
12
+
13
+ class Statistic:
14
+ """
15
+ Base class of every statistic, a single result computed from a set of values.
16
+
17
+ A statistic is immutable and checks its settings when it is created.
18
+
19
+ Only its subclasses are created: calling ``ndp.Statistic()`` raises ``RefusedOperationError``.
20
+
21
+ Every statistic, passed to ``Array.compute``, ``Calculation`` and ``Description``:
22
+
23
+ |Statistic|What it computes|Example|
24
+ |---|---|---|
25
+ |``Count``|Number of values, without the missing ones by default|``ndp.Count()``|
26
+ |``CountDistinct``|Number of distinct values that are not missing|``ndp.CountDistinct()``|
27
+ |``Sum``|Sum of the values|``ndp.Sum()``|
28
+ |``Mean``|Arithmetic mean of the values|``ndp.Mean()``|
29
+ |``Median``|Median of the values, the middle value once sorted|``ndp.Median()``|
30
+ |``Min``|Smallest value|``ndp.Min()``|
31
+ |``Max``|Largest value|``ndp.Max()``|
32
+ |``StandardDeviation``|How far the values spread around the mean|``ndp.StandardDeviation()``|
33
+ |``Quantile``|Value below which a given fraction of the values lies|``ndp.Quantile(0.9)``|
34
+ |``MostFrequent``|Value that appears the most often|``ndp.MostFrequent()``|
35
+ |``MostFrequentCount``|Number of times the most frequent value appears|``ndp.MostFrequentCount()``|
36
+
37
+ .. versionadded:: 0.1.0
38
+
39
+ Examples
40
+ --------
41
+ >>> import numdaplot as ndp
42
+ >>> prices = ndp.Array.from_list([10.0, 30.0])
43
+ >>> for statistic in [ndp.Min(), ndp.Mean(), ndp.Max()]:
44
+ ... print(prices.compute(statistic).to_value())
45
+ 10.0
46
+ 20.0
47
+ 30.0
48
+ """
49
+
50
+ def __init__(self) -> None:
51
+ """
52
+ Refuse the creation of the base class itself, and let a subclass be created.
53
+
54
+ .. versionadded:: 0.1.0
55
+
56
+ Raises
57
+ ------
58
+ RefusedOperationError
59
+ When the created object is a Statistic and not one of its subclasses.
60
+ """
61
+ created_class = type(self)
62
+ if created_class is Statistic:
63
+ raise RefusedOperationError(CONSTRUCTOR_OPERATION, CONSTRUCTOR_ALTERNATIVE)
@@ -0,0 +1,27 @@
1
+ """
2
+ Sum of the values 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 Sum(Statistic):
14
+ """
15
+ Sum of the values.
16
+
17
+ Missing values are ignored.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Examples
22
+ --------
23
+ >>> import numdaplot as ndp
24
+ >>> amounts = ndp.Array.from_list([10.5, None, 4.5])
25
+ >>> amounts.compute(ndp.Sum()).to_value()
26
+ 15.0
27
+ """
@@ -0,0 +1,5 @@
1
+ """
2
+ The ``ndp.Table`` class and its settings: files, filters, aggregations, columns, sorting and preview.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
@@ -0,0 +1,5 @@
1
+ """
2
+ Aggregation of the rows of a Table, as a whole or by group.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
@@ -0,0 +1,189 @@
1
+ """
2
+ Aggregation of the rows of a Table.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ import numpy
10
+ import pandas
11
+ from numpy.typing import NDArray
12
+
13
+ from numdaplot.statistics.statistic import Statistic
14
+ from numdaplot.tables.aggregation.aggregation import Aggregation
15
+ from numdaplot.tables.aggregation.calculation import find_result_name
16
+ from numdaplot.tables.aggregation.result_column import build_result_column, compute_cell
17
+ from numdaplot.tables.aggregation.row_groups import find_row_groups
18
+ from numdaplot.tables.columns.column_names import require_known_columns
19
+ from numdaplot.tables.frames.column import Column
20
+ from numdaplot.tables.frames.column_values import find_column_missing, read_present_values
21
+ from numdaplot.tables.frames.named_column_errors import NamedColumnErrors
22
+ from numdaplot.tables.frames.time_zones import attribute_source_time_zone
23
+
24
+ FIRST_ROW = 0
25
+ ROW_POSITION_DTYPE = numpy.int64
26
+
27
+
28
+ def aggregate_frame(frame: pandas.DataFrame, aggregation: Aggregation) -> pandas.DataFrame:
29
+ """
30
+ Return the statistics of the whole Table, or of each group of rows.
31
+
32
+ .. versionadded:: 0.1.0
33
+
34
+ Parameters
35
+ ----------
36
+ frame
37
+ The columns of a Table.
38
+ aggregation
39
+ The statistics and the group columns.
40
+
41
+ Returns
42
+ -------
43
+ pandas.DataFrame
44
+ One row per group, sorted by group values with missing values last, or a single row.
45
+ The group columns come first, then one column per calculation.
46
+
47
+ Raises
48
+ ------
49
+ ColumnNotFoundError
50
+ When a calculation or a group names a column the Table does not have.
51
+ IncompatibleTypesError
52
+ When a statistic does not apply to the type of its column.
53
+
54
+ Examples
55
+ --------
56
+ >>> import pandas
57
+ >>> import numdaplot as ndp
58
+ >>> from numdaplot.tables.aggregation.aggregated_frame import aggregate_frame
59
+ >>> frame = pandas.DataFrame({"city": ["Pau", "Lyon", "Pau"], "price": [1.0, 2.0, 3.0]})
60
+ >>> total = ndp.Calculation(column="price", function=ndp.Sum())
61
+ >>> aggregate_frame(frame, ndp.Aggregation(calculations=[total], group_by=["city"]))
62
+ city price_sum
63
+ 0 Lyon 2.0
64
+ 1 Pau 4.0
65
+ """
66
+ column_names = [str(column_name) for column_name in frame.columns]
67
+ calculation_columns = [calculation.column for calculation in aggregation.calculations]
68
+ require_known_columns(calculation_columns, column_names)
69
+ group_by = aggregation.group_by
70
+ if group_by is not None:
71
+ require_known_columns(group_by, column_names)
72
+
73
+ row_groups = find_row_groups(frame, group_by)
74
+ result_columns = dict[str, Column]()
75
+ if group_by is not None:
76
+ key_columns = take_group_keys(frame, group_by, row_groups)
77
+ result_columns.update(key_columns)
78
+
79
+ for calculation in aggregation.calculations:
80
+ result_name = find_result_name(calculation)
81
+ column = frame[calculation.column]
82
+ result_column = compute_group_results(column, calculation.function, row_groups)
83
+ result_columns[result_name] = result_column
84
+
85
+ group_count = len(row_groups)
86
+ group_numbers = pandas.RangeIndex(group_count)
87
+ aggregated_frame = pandas.DataFrame(result_columns, index=group_numbers)
88
+
89
+ return aggregated_frame
90
+
91
+
92
+ def take_group_keys(frame: pandas.DataFrame, group_by: list[str], row_groups: list[NDArray[Any]]) -> dict[str, Column]:
93
+ """
94
+ Return the values of the group columns for each group, taken from its first row.
95
+
96
+ .. versionadded:: 0.1.0
97
+
98
+ Parameters
99
+ ----------
100
+ frame
101
+ The columns of a Table.
102
+ group_by
103
+ The names of the group columns.
104
+ row_groups
105
+ The rows of each group.
106
+
107
+ Returns
108
+ -------
109
+ dict[str, Column]
110
+ One column per group column, one row per group, numbered from 0.
111
+
112
+ Examples
113
+ --------
114
+ >>> import numpy
115
+ >>> import pandas
116
+ >>> from numdaplot.tables.aggregation.aggregated_frame import take_group_keys
117
+ >>> frame = pandas.DataFrame({"city": ["Pau", "Lyon", "Pau"]})
118
+ >>> take_group_keys(frame, ["city"], [numpy.array([1]), numpy.array([0, 2])])["city"].tolist()
119
+ ['Lyon', 'Pau']
120
+ """
121
+ first_row_list = [row_group[FIRST_ROW] for row_group in row_groups]
122
+ first_rows = numpy.array(first_row_list, dtype=ROW_POSITION_DTYPE)
123
+ key_columns = dict[str, Column]()
124
+
125
+ for column_name in group_by:
126
+ column = frame[column_name]
127
+ first_values = column.iloc[first_rows]
128
+ key_column = first_values.reset_index(drop=True)
129
+ key_columns[column_name] = key_column
130
+
131
+ return key_columns
132
+
133
+
134
+ def compute_group_results(column: Column, statistic: Statistic, row_groups: list[NDArray[Any]]) -> Column:
135
+ """
136
+ Return a statistic of the values of a column, for each group of rows, missing values left out unless counted.
137
+
138
+ .. versionadded:: 0.1.0
139
+
140
+ Parameters
141
+ ----------
142
+ column
143
+ A Table column.
144
+ statistic
145
+ Any statistic of numdaplot.
146
+ row_groups
147
+ The rows of each group.
148
+
149
+ Returns
150
+ -------
151
+ Column
152
+ One result per group, missing for a group without present value when the statistic needs one.
153
+
154
+ Raises
155
+ ------
156
+ IncompatibleTypesError
157
+ When the statistic does not apply to the type of the column.
158
+
159
+ Examples
160
+ --------
161
+ >>> import numpy
162
+ >>> import pandas
163
+ >>> import numdaplot as ndp
164
+ >>> from numdaplot.tables.aggregation.aggregated_frame import compute_group_results
165
+ >>> column = pandas.Series([1.0, None, 3.0])
166
+ >>> compute_group_results(column, ndp.Mean(), [numpy.array([1]), numpy.array([0, 2])]).tolist()
167
+ [nan, 2.0]
168
+ """
169
+ missing = find_column_missing(column)
170
+ present = ~missing
171
+ present_values = read_present_values(column)
172
+ present_counts = numpy.cumsum(present)
173
+ value_positions = present_counts - 1
174
+ results = list[NDArray[Any] | None]()
175
+
176
+ with NamedColumnErrors(column):
177
+ for row_group in row_groups:
178
+ group_present = present[row_group]
179
+ present_rows = row_group[group_present]
180
+ group_value_positions = value_positions[present_rows]
181
+ group_values = present_values[group_value_positions]
182
+ group_size = len(row_group)
183
+ result = compute_cell(group_values, statistic, group_size)
184
+ results.append(result)
185
+
186
+ utc_results = build_result_column(results)
187
+ result_column = attribute_source_time_zone(utc_results, column)
188
+
189
+ return result_column
@@ -0,0 +1,97 @@
1
+ """
2
+ Settings of the aggregation of the rows of a Table.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from numdaplot.errors.empty_list_error import EmptyListError
10
+ from numdaplot.settings.field_types import require_field_types
11
+ from numdaplot.tables.aggregation.calculation import Calculation, find_result_name
12
+ from numdaplot.tables.columns.column_names import require_column_names, require_unique_names
13
+
14
+ CALCULATION_ITEM_NAME = "calculation"
15
+ GROUP_COLUMN_ITEM_NAME = "group column"
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class Aggregation:
20
+ """
21
+ Statistics computed on the whole Table or on each group of rows, used by ``Table.aggregate``.
22
+
23
+ .. versionadded:: 0.1.0
24
+
25
+ Parameters
26
+ ----------
27
+ calculations
28
+ The statistics to compute, at least one. The aggregation keeps its own copy of the list.
29
+ group_by
30
+ The names of the columns whose values form the groups: one result row per combination
31
+ of values. The whole Table gives a single row when omitted.
32
+
33
+ Raises
34
+ ------
35
+ InvalidTypeError
36
+ When a setting is not of the type its annotation names.
37
+ EmptyListError
38
+ When ``calculations`` or ``group_by`` is an empty list.
39
+ InvalidColumnNameError
40
+ When a group column name is an empty text.
41
+ DuplicateColumnError
42
+ When a name appears twice among the group columns and the result names.
43
+
44
+ Examples
45
+ --------
46
+ >>> import numdaplot as ndp
47
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
48
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
49
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
50
+ >>> average_price = ndp.Calculation(column="price", function=ndp.Mean())
51
+ >>> sales.aggregate(ndp.Aggregation(calculations=[average_price], group_by=["city"]))
52
+ city price_mean
53
+ TEXT FLOAT64
54
+ 0 Lyon 80.0
55
+ 1 Paris 135.0
56
+ """
57
+
58
+ calculations: list[Calculation]
59
+ group_by: list[str] | None = None
60
+
61
+ def __post_init__(self) -> None:
62
+ """
63
+ Check the lists and replace them with copies that only the aggregation holds.
64
+
65
+ .. versionadded:: 0.1.0
66
+
67
+ Raises
68
+ ------
69
+ InvalidTypeError
70
+ When a setting is not of the type its annotation names.
71
+ EmptyListError
72
+ When ``calculations`` or ``group_by`` is an empty list.
73
+ InvalidColumnNameError
74
+ When a group column name is an empty text.
75
+ DuplicateColumnError
76
+ When a name appears twice among the group columns and the result names.
77
+ """
78
+ require_field_types(self)
79
+
80
+ if self.calculations == []:
81
+ raise EmptyListError(CALCULATION_ITEM_NAME)
82
+
83
+ if self.group_by == []:
84
+ raise EmptyListError(GROUP_COLUMN_ITEM_NAME)
85
+
86
+ calculations_copy = list(self.calculations)
87
+ object.__setattr__(self, "calculations", calculations_copy)
88
+ output_names = list[str]()
89
+ if self.group_by is not None:
90
+ require_column_names(self.group_by)
91
+ group_by_copy = list(self.group_by)
92
+ object.__setattr__(self, "group_by", group_by_copy)
93
+ output_names.extend(group_by_copy)
94
+
95
+ result_names = [find_result_name(calculation) for calculation in calculations_copy]
96
+ output_names.extend(result_names)
97
+ require_unique_names(output_names)