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,74 @@
1
+ """
2
+ Settings of the filter 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.filtering.condition import Condition
12
+ from numdaplot.tables.filtering.filter_mode import FilterMode
13
+
14
+ CONDITION_ITEM_NAME = "condition"
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class Filter:
19
+ """
20
+ Conditions a row must satisfy to be kept, used by ``Table.filter``.
21
+
22
+ .. versionadded:: 0.1.0
23
+
24
+ Parameters
25
+ ----------
26
+ conditions
27
+ The conditions, at least one. The filter keeps its own copy of the list.
28
+ mode
29
+ Whether a row must satisfy every condition, ``FilterMode.ALL`` by default, or at least one, ``FilterMode.ANY``.
30
+
31
+ Raises
32
+ ------
33
+ InvalidTypeError
34
+ When a setting is not of the type its annotation names.
35
+ EmptyListError
36
+ When ``conditions`` is empty.
37
+
38
+ Examples
39
+ --------
40
+ >>> import numdaplot as ndp
41
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
42
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
43
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
44
+ >>> expensive = ndp.Condition(rule=ndp.Greater(100), columns=["price"])
45
+ >>> in_lyon = ndp.Condition(rule=ndp.Equal("Lyon"), columns=["city"])
46
+ >>> sales.filter(ndp.Filter(conditions=[expensive, in_lyon]))
47
+ city price
48
+ TEXT FLOAT64
49
+ (0 rows)
50
+ """
51
+
52
+ conditions: list[Condition]
53
+ mode: FilterMode = FilterMode.ALL
54
+
55
+ def __post_init__(self) -> None:
56
+ """
57
+ Check that there is a condition and replace the list with a copy that only the filter holds.
58
+
59
+ .. versionadded:: 0.1.0
60
+
61
+ Raises
62
+ ------
63
+ InvalidTypeError
64
+ When a setting is not of the type its annotation names.
65
+ EmptyListError
66
+ When ``conditions`` is empty.
67
+ """
68
+ require_field_types(self)
69
+
70
+ if self.conditions == []:
71
+ raise EmptyListError(CONDITION_ITEM_NAME)
72
+
73
+ conditions_copy = list(self.conditions)
74
+ object.__setattr__(self, "conditions", conditions_copy)
@@ -0,0 +1,67 @@
1
+ """
2
+ How the conditions of a Filter combine.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from enum import Enum, auto
8
+
9
+
10
+ class FilterMode(Enum):
11
+ """
12
+ How the conditions of a ``Filter`` combine to keep a row.
13
+
14
+ .. versionadded:: 0.1.0
15
+
16
+ Examples
17
+ --------
18
+ >>> import numdaplot as ndp
19
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
20
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
21
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
22
+ >>> expensive = ndp.Condition(rule=ndp.Greater(130), columns=["price"])
23
+ >>> in_lyon = ndp.Condition(rule=ndp.Equal("Lyon"), columns=["city"])
24
+ >>> sales.filter(ndp.Filter(conditions=[expensive, in_lyon], mode=ndp.FilterMode.ANY))
25
+ city price
26
+ TEXT FLOAT64
27
+ 0 Lyon 80.0
28
+ 1 Paris 150.0
29
+ """
30
+
31
+ ALL = auto()
32
+ """
33
+ A row is kept when it satisfies every condition. Default value.
34
+
35
+ Examples
36
+ --------
37
+ >>> import numdaplot as ndp
38
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
39
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
40
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
41
+ >>> expensive = ndp.Condition(rule=ndp.Greater(100), columns=["price"])
42
+ >>> in_lyon = ndp.Condition(rule=ndp.Equal("Lyon"), columns=["city"])
43
+ >>> sales.filter(ndp.Filter(conditions=[expensive, in_lyon], mode=ndp.FilterMode.ALL))
44
+ city price
45
+ TEXT FLOAT64
46
+ (0 rows)
47
+ """
48
+
49
+ ANY = auto()
50
+ """
51
+ A row is kept when it satisfies at least one condition.
52
+
53
+ Examples
54
+ --------
55
+ >>> import numdaplot as ndp
56
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
57
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
58
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
59
+ >>> expensive = ndp.Condition(rule=ndp.Greater(100), columns=["price"])
60
+ >>> in_lyon = ndp.Condition(rule=ndp.Equal("Lyon"), columns=["city"])
61
+ >>> sales.filter(ndp.Filter(conditions=[expensive, in_lyon], mode=ndp.FilterMode.ANY))
62
+ city price
63
+ TEXT FLOAT64
64
+ 0 Paris 120.0
65
+ 1 Lyon 80.0
66
+ 2 Paris 150.0
67
+ """
@@ -0,0 +1,152 @@
1
+ """
2
+ Rows of a Table satisfying a Filter.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ import numpy
8
+ import pandas
9
+ from numpy.typing import NDArray
10
+
11
+ from numdaplot.tables.columns.column_names import require_known_columns
12
+ from numdaplot.tables.filtering.column_mask import build_column_mask
13
+ from numdaplot.tables.filtering.column_match import ColumnMatch
14
+ from numdaplot.tables.filtering.condition import Condition
15
+ from numdaplot.tables.filtering.filter import Filter
16
+ from numdaplot.tables.filtering.filter_mode import FilterMode
17
+
18
+ MASK_AXIS = 0
19
+
20
+
21
+ def build_filter_mask(frame: pandas.DataFrame, row_filter: Filter) -> NDArray[numpy.bool_]:
22
+ """
23
+ Return which rows of a Table satisfy a Filter.
24
+
25
+ .. versionadded:: 0.1.0
26
+
27
+ Parameters
28
+ ----------
29
+ frame
30
+ The columns of a Table.
31
+ row_filter
32
+ The conditions and how they combine.
33
+
34
+ Returns
35
+ -------
36
+ NDArray[numpy.bool_]
37
+ True at each row to keep.
38
+
39
+ Raises
40
+ ------
41
+ ColumnNotFoundError
42
+ When a condition names a column the Table does not have.
43
+ IncompatibleTypesError
44
+ When a rule does not apply to the type of one of its columns.
45
+
46
+ Examples
47
+ --------
48
+ >>> import pandas
49
+ >>> import numdaplot as ndp
50
+ >>> from numdaplot.tables.filtering.row_mask import build_filter_mask
51
+ >>> frame = pandas.DataFrame({"price": [5.0, 12.0]})
52
+ >>> build_filter_mask(frame, ndp.Filter(conditions=[ndp.Condition(rule=ndp.Greater(10))]))
53
+ array([False, True])
54
+ """
55
+ condition_masks = [build_condition_mask(frame, condition) for condition in row_filter.conditions]
56
+ requires_all = row_filter.mode == FilterMode.ALL
57
+ row_count = len(frame)
58
+ filter_mask = combine_masks(condition_masks, requires_all, row_count)
59
+
60
+ return filter_mask
61
+
62
+
63
+ def build_condition_mask(frame: pandas.DataFrame, condition: Condition) -> NDArray[numpy.bool_]:
64
+ """
65
+ Return which rows of a Table satisfy a Condition.
66
+
67
+ .. versionadded:: 0.1.0
68
+
69
+ Parameters
70
+ ----------
71
+ frame
72
+ The columns of a Table.
73
+ condition
74
+ The rule, its columns, and how the columns combine.
75
+
76
+ Returns
77
+ -------
78
+ NDArray[numpy.bool_]
79
+ True at each row satisfying the condition.
80
+
81
+ Raises
82
+ ------
83
+ ColumnNotFoundError
84
+ When the condition names a column the Table does not have.
85
+ IncompatibleTypesError
86
+ When the rule does not apply to the type of one of the columns.
87
+
88
+ Examples
89
+ --------
90
+ >>> import pandas
91
+ >>> import numdaplot as ndp
92
+ >>> from numdaplot.tables.filtering.row_mask import build_condition_mask
93
+ >>> frame = pandas.DataFrame({"low": [1.0, 5.0], "high": [2.0, 9.0]})
94
+ >>> build_condition_mask(frame, ndp.Condition(rule=ndp.Greater(1.5), mode=ndp.ColumnMatch.ALL))
95
+ array([False, True])
96
+ """
97
+ column_names = [str(column_name) for column_name in frame.columns]
98
+ if condition.columns is not None:
99
+ require_known_columns(condition.columns, column_names)
100
+ column_names = condition.columns
101
+
102
+ column_masks = list[NDArray[numpy.bool_]]()
103
+
104
+ for column_name in column_names:
105
+ column = frame[column_name]
106
+ column_mask = build_column_mask(column, condition.rule)
107
+ column_masks.append(column_mask)
108
+
109
+ requires_all = condition.mode == ColumnMatch.ALL
110
+ row_count = len(frame)
111
+ condition_mask = combine_masks(column_masks, requires_all, row_count)
112
+
113
+ return condition_mask
114
+
115
+
116
+ def combine_masks(masks: list[NDArray[numpy.bool_]], requires_all: bool, row_count: int) -> NDArray[numpy.bool_]:
117
+ """
118
+ Return the rows satisfying every mask, or at least one mask.
119
+
120
+ .. versionadded:: 0.1.0
121
+
122
+ Parameters
123
+ ----------
124
+ masks
125
+ One mask per condition or per column, each as long as the Table.
126
+ requires_all
127
+ True to keep the rows satisfying every mask, False for at least one.
128
+ row_count
129
+ The number of rows of the Table, used when there is no mask.
130
+
131
+ Returns
132
+ -------
133
+ NDArray[numpy.bool_]
134
+ The combined mask. Without any mask, every row satisfies "every mask" and none satisfies "at least one".
135
+
136
+ Examples
137
+ --------
138
+ >>> import numpy
139
+ >>> from numdaplot.tables.filtering.row_mask import combine_masks
140
+ >>> combine_masks([numpy.array([True, False]), numpy.array([True, True])], True, 2)
141
+ array([ True, False])
142
+ """
143
+ mask_count = len(masks)
144
+ stacked_masks = numpy.array(masks, dtype=numpy.bool_)
145
+ mask_grid = stacked_masks.reshape(mask_count, row_count)
146
+ if requires_all:
147
+ every_mask = numpy.logical_and.reduce(mask_grid, axis=MASK_AXIS)
148
+ return every_mask
149
+
150
+ any_mask = numpy.logical_or.reduce(mask_grid, axis=MASK_AXIS)
151
+
152
+ return any_mask
@@ -0,0 +1,164 @@
1
+ """
2
+ Datetimes of a rule matched with the time zone of the column it is applied to.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ import dataclasses
8
+ from datetime import UTC, date, datetime
9
+ from typing import Any, cast
10
+
11
+ from numdaplot.dates.time_zone import TimeZone
12
+ from numdaplot.errors.time_zone_mismatch_error import TimeZoneMismatchError
13
+ from numdaplot.rules.rule import Rule
14
+
15
+ NAIVE_COLUMN_OPERATION = "A rule on a column without time zone"
16
+ ZONE_COLUMN_OPERATION = "A rule on a datetime column with a time zone"
17
+
18
+
19
+ def match_rule_time_zone(rule: Rule, time_zone: TimeZone | None) -> Rule:
20
+ """
21
+ Return a rule whose dates and datetimes can be compared with the values of a column.
22
+
23
+ A column with a time zone is compared through its UTC clock times, so the datetimes of the rule are
24
+ moved to UTC too.
25
+
26
+ .. versionadded:: 0.1.0
27
+
28
+ Parameters
29
+ ----------
30
+ rule
31
+ Any rule of numdaplot.
32
+ time_zone
33
+ The time zone of the column, ``None`` when it has none.
34
+
35
+ Returns
36
+ -------
37
+ Rule
38
+ The rule itself for a column without time zone, or a copy with its datetimes as UTC clock times
39
+ without zone.
40
+
41
+ Raises
42
+ ------
43
+ TimeZoneMismatchError
44
+ When the rule has a datetime with a time zone and the column has none, or the column has a zone and
45
+ the rule has a date or a datetime without zone.
46
+
47
+ Examples
48
+ --------
49
+ >>> from datetime import datetime
50
+ >>> from zoneinfo import ZoneInfo
51
+ >>> import numdaplot as ndp
52
+ >>> from numdaplot.tables.filtering.rule_moments import match_rule_time_zone
53
+ >>> paris_noon = datetime(2026, 7, 1, 12, tzinfo=ZoneInfo("Europe/Paris"))
54
+ >>> match_rule_time_zone(ndp.Greater(paris_noon), ndp.TimeZone("Europe/Paris"))
55
+ Greater(value=datetime.datetime(2026, 7, 1, 10, 0))
56
+ """
57
+ if not dataclasses.is_dataclass(rule):
58
+ return rule
59
+
60
+ rule_fields = dataclasses.fields(rule)
61
+ matched_values = dict[str, Any]()
62
+
63
+ for rule_field in rule_fields:
64
+ field_value = getattr(rule, rule_field.name)
65
+ matched_values[rule_field.name] = match_field_time_zone(field_value, time_zone)
66
+
67
+ if time_zone is None:
68
+ return rule
69
+
70
+ matched_rule = dataclasses.replace(rule, **matched_values)
71
+
72
+ return matched_rule
73
+
74
+
75
+ def match_field_time_zone(field_value: Any, time_zone: TimeZone | None) -> Any:
76
+ """
77
+ Return the value of a rule setting with its dates and datetimes matched with the zone of a column.
78
+
79
+ .. versionadded:: 0.1.0
80
+
81
+ Parameters
82
+ ----------
83
+ field_value
84
+ The value of a setting of a rule, a single value or a list of values.
85
+ time_zone
86
+ The time zone of the column, ``None`` when it has none.
87
+
88
+ Returns
89
+ -------
90
+ Any
91
+ The value, a datetime moved to a UTC clock time without zone, or a list of such values.
92
+
93
+ Raises
94
+ ------
95
+ TimeZoneMismatchError
96
+ When a date or a datetime does not match the zone state of the column.
97
+
98
+ Examples
99
+ --------
100
+ >>> from numdaplot.tables.filtering.rule_moments import match_field_time_zone
101
+ >>> match_field_time_zone([1, 2], None)
102
+ [1, 2]
103
+ """
104
+ if isinstance(field_value, list):
105
+ list_values = cast(list[Any], field_value)
106
+ matched_list = [match_moment_time_zone(list_value, time_zone) for list_value in list_values]
107
+ return matched_list
108
+
109
+ matched_value = match_moment_time_zone(field_value, time_zone)
110
+
111
+ return matched_value
112
+
113
+
114
+ def match_moment_time_zone(value: Any, time_zone: TimeZone | None) -> Any:
115
+ """
116
+ Return a single value of a rule with its date or datetime matched with the zone of a column.
117
+
118
+ .. versionadded:: 0.1.0
119
+
120
+ Parameters
121
+ ----------
122
+ value
123
+ A single value of a rule.
124
+ time_zone
125
+ The time zone of the column, ``None`` when it has none.
126
+
127
+ Returns
128
+ -------
129
+ Any
130
+ The value itself, or a datetime with a zone moved to a UTC clock time without zone.
131
+
132
+ Raises
133
+ ------
134
+ TimeZoneMismatchError
135
+ When the value is a datetime with a zone and the column has none, or the column has a zone and the value
136
+ is a date or a datetime without zone.
137
+
138
+ Examples
139
+ --------
140
+ >>> from datetime import datetime
141
+ >>> from zoneinfo import ZoneInfo
142
+ >>> import numdaplot as ndp
143
+ >>> from numdaplot.tables.filtering.rule_moments import match_moment_time_zone
144
+ >>> match_moment_time_zone(datetime(2026, 1, 1, 9, tzinfo=ZoneInfo("Europe/Paris")), ndp.TimeZone("UTC"))
145
+ datetime.datetime(2026, 1, 1, 8, 0)
146
+ """
147
+ if not isinstance(value, date):
148
+ return value
149
+
150
+ has_zone = isinstance(value, datetime) and value.tzinfo is not None
151
+ if time_zone is None and has_zone:
152
+ raise TimeZoneMismatchError(NAIVE_COLUMN_OPERATION, False)
153
+
154
+ if time_zone is None:
155
+ return value
156
+
157
+ if not has_zone:
158
+ raise TimeZoneMismatchError(ZONE_COLUMN_OPERATION, True)
159
+
160
+ zone_datetime = cast(datetime, value)
161
+ utc_datetime = zone_datetime.astimezone(UTC)
162
+ naive_datetime = utc_datetime.replace(tzinfo=None)
163
+
164
+ return naive_datetime
@@ -0,0 +1,5 @@
1
+ """
2
+ Storage of Table columns in pandas: normalization, conversion to numpy, equality, text and positions.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
@@ -0,0 +1,95 @@
1
+ """
2
+ Columns of a Table built from Arrays.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING
10
+
11
+ import pandas
12
+
13
+ from numdaplot.arrays.array_data import read_stored_values
14
+ from numdaplot.errors.dimension_error import DimensionError
15
+ from numdaplot.errors.empty_list_error import EmptyListError
16
+ from numdaplot.errors.shape_mismatch_error import ShapeMismatchError
17
+ from numdaplot.tables.columns.column_names import require_column_names
18
+ from numdaplot.tables.frames.column import Column
19
+ from numdaplot.tables.frames.column_values import build_column
20
+ from numdaplot.tables.frames.time_range_errors import TimeRangeErrors
21
+
22
+ if TYPE_CHECKING:
23
+ from numdaplot.arrays.array import Array
24
+
25
+ FROM_ARRAYS_OPERATION = "from_arrays"
26
+ COLUMN_ITEM_NAME = "column"
27
+ ONE_DIMENSION = 1
28
+
29
+
30
+ def build_array_frame(columns: dict[str, Array]) -> pandas.DataFrame:
31
+ """
32
+ Return the columns of a Table holding the values of one-dimensional Arrays.
33
+
34
+ .. versionadded:: 0.1.0
35
+
36
+ Parameters
37
+ ----------
38
+ columns
39
+ One Array per column, by column name, all of the same length.
40
+
41
+ Returns
42
+ -------
43
+ pandas.DataFrame
44
+ The columns in the order of the dictionary, rows numbered from 0.
45
+
46
+ Raises
47
+ ------
48
+ EmptyListError
49
+ When there is no column.
50
+ InvalidColumnNameError
51
+ When a column name is not a non-empty text.
52
+ DimensionError
53
+ When an Array does not have one dimension.
54
+ ShapeMismatchError
55
+ When the Arrays do not have the same length.
56
+ TimeOverflowError
57
+ When an Array holds a datetime or a duration that nanoseconds cannot hold.
58
+
59
+ Examples
60
+ --------
61
+ >>> import numdaplot as ndp
62
+ >>> from numdaplot.tables.frames.array_frame import build_array_frame
63
+ >>> build_array_frame({"city": ndp.Array.from_list(["Pau"]), "price": ndp.Array.from_list([1.5])})
64
+ city price
65
+ 0 Pau 1.5
66
+ """
67
+ if columns == {}:
68
+ raise EmptyListError(COLUMN_ITEM_NAME)
69
+
70
+ column_names = list(columns)
71
+ require_column_names(column_names)
72
+ built_columns = dict[str, Column]()
73
+ value_counts = list[int]()
74
+
75
+ for column_name, array in columns.items():
76
+ values = read_stored_values(array)
77
+ if values.ndim != ONE_DIMENSION:
78
+ raise DimensionError(FROM_ARRAYS_OPERATION, values.ndim)
79
+
80
+ with TimeRangeErrors(FROM_ARRAYS_OPERATION, column_name):
81
+ column = build_column(values)
82
+
83
+ built_columns[column_name] = column
84
+ value_counts.append(values.size)
85
+
86
+ row_count = value_counts[0]
87
+
88
+ for value_count in value_counts:
89
+ if value_count != row_count:
90
+ raise ShapeMismatchError((row_count,), (value_count,))
91
+
92
+ row_numbers = pandas.RangeIndex(row_count)
93
+ frame = pandas.DataFrame(built_columns, index=row_numbers)
94
+
95
+ return frame
@@ -0,0 +1,132 @@
1
+ r"""
2
+ Cleaning of the column names a Table reads.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from collections.abc import Hashable
8
+
9
+ import pandas
10
+
11
+ from numdaplot.errors.duplicate_column_error import DuplicateColumnError
12
+ from numdaplot.tables.files.column_names import ColumnNames
13
+
14
+
15
+ def clean_frame_names(frame: pandas.DataFrame, column_names: ColumnNames) -> pandas.DataFrame:
16
+ r"""
17
+ Return a DataFrame read from outside numdaplot, with its column names cleaned when asked.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Parameters
22
+ ----------
23
+ frame
24
+ A DataFrame read from a file or given by the user. It is not changed.
25
+ column_names
26
+ ``CLEANED`` to remove the spaces, tabs and line breaks at the start and the end of each name, ``KEPT`` to
27
+ keep the names as written.
28
+
29
+ Returns
30
+ -------
31
+ pandas.DataFrame
32
+ The DataFrame with the cleaned names, or the same DataFrame when the names are kept.
33
+
34
+ Raises
35
+ ------
36
+ DuplicateColumnError
37
+ When two different names become the same once cleaned.
38
+
39
+ Examples
40
+ --------
41
+ >>> import pandas
42
+ >>> import numdaplot as ndp
43
+ >>> from numdaplot.tables.frames.cleaned_names import clean_frame_names
44
+ >>> frame = pandas.DataFrame({"id_vehicule\n": [1], " speed ": [50]})
45
+ >>> clean_frame_names(frame, ndp.ColumnNames.CLEANED).columns.tolist()
46
+ ['id_vehicule', 'speed']
47
+ """
48
+ if column_names == ColumnNames.KEPT:
49
+ return frame
50
+
51
+ raw_names = list[Hashable](frame.columns)
52
+ cleaned_names = clean_names(raw_names)
53
+ require_distinct_cleaned_names(raw_names, cleaned_names)
54
+ cleaned_frame = frame.copy(deep=False)
55
+ cleaned_frame.columns = pandas.Index(cleaned_names)
56
+
57
+ return cleaned_frame
58
+
59
+
60
+ def clean_names(names: list[Hashable]) -> list[Hashable]:
61
+ r"""
62
+ Return column names without the spaces, tabs and line breaks at their start and end.
63
+
64
+ A name that is not a text is kept, so that the check of the column names refuses it.
65
+
66
+ .. versionadded:: 0.1.0
67
+
68
+ Parameters
69
+ ----------
70
+ names
71
+ The column names.
72
+
73
+ Returns
74
+ -------
75
+ list[Hashable]
76
+ The cleaned names, in the same order.
77
+
78
+ Examples
79
+ --------
80
+ >>> from numdaplot.tables.frames.cleaned_names import clean_names
81
+ >>> clean_names(["id_vehicule\n", " speed", 2024])
82
+ ['id_vehicule', 'speed', 2024]
83
+ """
84
+ cleaned_names = list[Hashable]()
85
+ for name in names:
86
+ cleaned_name = name
87
+ if isinstance(name, str):
88
+ cleaned_name = name.strip()
89
+
90
+ cleaned_names.append(cleaned_name)
91
+
92
+ return cleaned_names
93
+
94
+
95
+ def require_distinct_cleaned_names(raw_names: list[Hashable], cleaned_names: list[Hashable]) -> None:
96
+ r"""
97
+ Check that two different names do not become the same once cleaned.
98
+
99
+ A name written twice the same way is left to the check of the column names, which names it alone.
100
+
101
+ .. versionadded:: 0.1.0
102
+
103
+ Parameters
104
+ ----------
105
+ raw_names
106
+ The column names as written.
107
+ cleaned_names
108
+ The same names once cleaned, in the same order.
109
+
110
+ Raises
111
+ ------
112
+ DuplicateColumnError
113
+ At the first cleaned name coming from two different names, with both of them.
114
+
115
+ Examples
116
+ --------
117
+ >>> import numdaplot as ndp
118
+ >>> from numdaplot.tables.frames.cleaned_names import require_distinct_cleaned_names
119
+ >>> try:
120
+ ... require_distinct_cleaned_names(["id", "id\n"], ["id", "id"])
121
+ ... except ndp.DuplicateColumnError as error:
122
+ ... print(error)
123
+ The column names 'id' and 'id\n' both become 'id' once cleaned. Use ColumnNames.KEPT to keep them as written.
124
+ """
125
+ first_raw_names = dict[Hashable, Hashable]()
126
+ for raw_name, cleaned_name in zip(raw_names, cleaned_names, strict=True):
127
+ first_raw_name = first_raw_names.setdefault(cleaned_name, raw_name)
128
+ if first_raw_name == raw_name:
129
+ continue
130
+
131
+ original_names = [str(first_raw_name), str(raw_name)]
132
+ raise DuplicateColumnError(str(cleaned_name), original_names)
@@ -0,0 +1,15 @@
1
+ """
2
+ Type of the pandas columns a Table stores.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ import pandas
10
+
11
+ type Column = pandas.Series[Any]
12
+ """A pandas column of a Table, stored with one of the dtypes given by ``to_pandas_dtype``.
13
+
14
+ .. versionadded:: 0.1.0
15
+ """