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,459 @@
1
+ """
2
+ Normalization of a pandas DataFrame into the storage of a Table.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from datetime import datetime
8
+ from typing import Any, cast
9
+
10
+ import numpy
11
+ import pandas
12
+ from pandas.api.types import infer_dtype
13
+
14
+ from numdaplot.data_types.numpy_mapping import from_numpy_dtype
15
+ from numdaplot.data_types.pandas_mapping import TYPES_BY_PANDAS_NAME, from_pandas_dtype, to_pandas_dtype
16
+ from numdaplot.data_types.time_of_day import holds_only_times
17
+ from numdaplot.data_types.type import Type
18
+ from numdaplot.errors.unsupported_index_error import UnsupportedIndexError
19
+ from numdaplot.tables.columns.column_names import require_column_names
20
+ from numdaplot.tables.frames.column import Column
21
+ from numdaplot.tables.frames.time_columns import is_time_column, read_object_values, store_time_column
22
+ from numdaplot.tables.frames.time_range_errors import TimeRangeErrors
23
+ from numdaplot.tables.frames.time_zones import normalize_time_zone_column
24
+
25
+ INFERRED_TYPES = {
26
+ "integer": Type.INT64,
27
+ "floating": Type.FLOAT64,
28
+ "mixed-integer-float": Type.FLOAT64,
29
+ "decimal": Type.FLOAT64,
30
+ "boolean": Type.BOOL,
31
+ "timedelta": Type.DURATION,
32
+ }
33
+ MOMENT_KINDS = frozenset({"date", "datetime"})
34
+ INTEGER_KINDS = frozenset({"i", "u"})
35
+ BOOLEAN_KIND = "b"
36
+ DECIMAL_KIND = "f"
37
+ DATETIME_KIND = "M"
38
+ DURATION_KIND = "m"
39
+ TEXT_INFERRED_KINDS = frozenset({"string", "empty"})
40
+ DATETIME_DTYPE = "datetime64[ns]"
41
+ DURATION_DTYPE = "timedelta64[ns]"
42
+ PYTHON_OBJECT_DTYPE = numpy.dtype(object)
43
+ TABLE_CREATION_OPERATION = "Table creation"
44
+
45
+
46
+ def normalize_frame(frame: pandas.DataFrame) -> pandas.DataFrame:
47
+ """
48
+ Return a DataFrame stored the way a Table stores its columns.
49
+
50
+ .. versionadded:: 0.1.0
51
+
52
+ Parameters
53
+ ----------
54
+ frame
55
+ Any DataFrame, read from a file or given by the user. It is not changed.
56
+
57
+ Returns
58
+ -------
59
+ pandas.DataFrame
60
+ A new DataFrame numbered from 0, whose columns use the dtypes given by ``to_pandas_dtype``.
61
+
62
+ Raises
63
+ ------
64
+ InvalidColumnNameError
65
+ When a column name is not a non-empty text.
66
+ DuplicateColumnError
67
+ When a column name appears twice.
68
+ UnsupportedIndexError
69
+ When the index holds anything else than the row numbers 0, 1, 2...
70
+ UnsupportedTypeError
71
+ When a column has a type numdaplot does not support, such as complex numbers.
72
+
73
+ Examples
74
+ --------
75
+ >>> import pandas
76
+ >>> from numdaplot.tables.frames.frame_normalization import normalize_frame
77
+ >>> normalize_frame(pandas.DataFrame({"count": [1, 2]})).dtypes.tolist()
78
+ [Int64Dtype()]
79
+ """
80
+ raw_names = list(frame.columns)
81
+ require_column_names(raw_names)
82
+ require_plain_index(frame.index)
83
+ column_names = [str(raw_name) for raw_name in raw_names]
84
+ normalized_columns = dict[str, Column]()
85
+
86
+ for column_name in column_names:
87
+ column = frame[column_name]
88
+ with TimeRangeErrors(TABLE_CREATION_OPERATION, column_name):
89
+ normalized_column = normalize_column(column)
90
+
91
+ normalized_columns[column_name] = normalized_column
92
+
93
+ row_count = len(frame)
94
+ row_numbers = pandas.RangeIndex(row_count)
95
+ normalized_frame = pandas.DataFrame(normalized_columns, index=row_numbers)
96
+
97
+ return normalized_frame
98
+
99
+
100
+ def require_plain_index(index: pandas.Index) -> None:
101
+ """
102
+ Check that an index only holds the row numbers 0, 1, 2...
103
+
104
+ .. versionadded:: 0.1.0
105
+
106
+ Parameters
107
+ ----------
108
+ index
109
+ The index of a DataFrame.
110
+
111
+ Raises
112
+ ------
113
+ UnsupportedIndexError
114
+ When the index holds other values, such as city names.
115
+
116
+ Examples
117
+ --------
118
+ >>> import numdaplot as ndp
119
+ >>> import pandas
120
+ >>> from numdaplot.tables.frames.frame_normalization import require_plain_index
121
+ >>> try:
122
+ ... require_plain_index(pandas.Index(["Paris", "Lyon"]))
123
+ ... except ndp.UnsupportedIndexError as error:
124
+ ... print(error)
125
+ A Table has no index, call reset_index() on the pandas DataFrame first to keep its index as a column.
126
+ """
127
+ row_count = len(index)
128
+ row_numbers = pandas.RangeIndex(row_count)
129
+ is_plain = index.equals(row_numbers)
130
+ if not is_plain:
131
+ raise UnsupportedIndexError()
132
+
133
+
134
+ def normalize_column(column: Column) -> Column:
135
+ """
136
+ Return a column stored with the pandas dtype of its numdaplot type.
137
+
138
+ .. versionadded:: 0.1.0
139
+
140
+ Parameters
141
+ ----------
142
+ column
143
+ Any pandas column.
144
+
145
+ Returns
146
+ -------
147
+ pandas.Series
148
+ The column itself when its dtype is already one a Table uses, otherwise a converted copy.
149
+ Python objects become integers, decimals or booleans when they all are, and texts otherwise.
150
+
151
+ Raises
152
+ ------
153
+ UnsupportedTypeError
154
+ When the column has a type numdaplot does not support, such as complex numbers or
155
+ datetimes in a fixed offset instead of a time zone.
156
+
157
+ Examples
158
+ --------
159
+ >>> import pandas
160
+ >>> from numdaplot.tables.frames.frame_normalization import normalize_column
161
+ >>> text_column = normalize_column(pandas.Series(["a", None], dtype=object))
162
+ >>> str(text_column.dtype)
163
+ 'string'
164
+ """
165
+ dtype_name = str(column.dtype)
166
+ if dtype_name in TYPES_BY_PANDAS_NAME:
167
+ stored_column = normalize_categories(column)
168
+ return stored_column
169
+
170
+ converted_column = convert_column_dtype(column)
171
+ from_pandas_dtype(converted_column.dtype)
172
+
173
+ return converted_column
174
+
175
+
176
+ def convert_column_dtype(column: Column) -> Column:
177
+ """
178
+ Return a column converted to the dtype a Table uses for its kind of values.
179
+
180
+ .. versionadded:: 0.1.0
181
+
182
+ Parameters
183
+ ----------
184
+ column
185
+ A column whose dtype is not one a Table uses.
186
+
187
+ Returns
188
+ -------
189
+ pandas.Series
190
+ The converted column, or the column itself when no conversion applies.
191
+
192
+ Raises
193
+ ------
194
+ UnsupportedTypeError
195
+ When the column holds datetimes in a fixed offset instead of a time zone.
196
+
197
+ Examples
198
+ --------
199
+ >>> import numpy
200
+ >>> import pandas
201
+ >>> from numdaplot.tables.frames.frame_normalization import convert_column_dtype
202
+ >>> convert_column_dtype(pandas.Series([1, 2], dtype=numpy.int32)).dtype
203
+ Int32Dtype()
204
+ """
205
+ column_dtype = column.dtype
206
+ dtype_kind = column_dtype.kind
207
+ if isinstance(column_dtype, pandas.DatetimeTZDtype):
208
+ time_zone_column = normalize_time_zone_column(column)
209
+ return time_zone_column
210
+
211
+ if isinstance(column_dtype, pandas.StringDtype):
212
+ text_column = convert_to_type(column, Type.TEXT)
213
+ return text_column
214
+
215
+ if dtype_kind == DECIMAL_KIND:
216
+ decimal_column = convert_decimals(column)
217
+ return decimal_column
218
+
219
+ if dtype_kind == DATETIME_KIND:
220
+ datetime_column = column.astype(DATETIME_DTYPE)
221
+ return datetime_column
222
+
223
+ if is_time_column(column):
224
+ return column
225
+
226
+ if dtype_kind == DURATION_KIND:
227
+ duration_column = column.astype(DURATION_DTYPE)
228
+ return duration_column
229
+
230
+ is_numpy_dtype = isinstance(column_dtype, numpy.dtype)
231
+ if not is_numpy_dtype:
232
+ return column
233
+
234
+ converted_column = convert_numpy_column(column)
235
+
236
+ return converted_column
237
+
238
+
239
+ def convert_decimals(column: Column) -> Column:
240
+ """
241
+ Return a decimal column stored as numpy decimals, with NaN as missing value.
242
+
243
+ .. versionadded:: 0.1.0
244
+
245
+ Parameters
246
+ ----------
247
+ column
248
+ A decimal column, such as the pandas ``Float64`` dtype that marks missing values with ``pd.NA``.
249
+
250
+ Returns
251
+ -------
252
+ pandas.Series
253
+ The column with the numpy decimal dtype of the same size.
254
+
255
+ Examples
256
+ --------
257
+ >>> import pandas
258
+ >>> from numdaplot.tables.frames.frame_normalization import convert_decimals
259
+ >>> convert_decimals(pandas.Series([1.5, None], dtype="Float64")).tolist()
260
+ [1.5, nan]
261
+ """
262
+ dtype_name = str(column.dtype)
263
+ numpy_dtype_name = dtype_name.lower()
264
+ decimal_values = column.to_numpy(dtype=numpy_dtype_name, na_value=numpy.nan)
265
+ decimal_column = pandas.Series(decimal_values, index=column.index)
266
+
267
+ return decimal_column
268
+
269
+
270
+ def convert_numpy_column(column: Column) -> Column:
271
+ """
272
+ Return a numpy integer, boolean or object column stored with the dtype a Table uses.
273
+
274
+ .. versionadded:: 0.1.0
275
+
276
+ Parameters
277
+ ----------
278
+ column
279
+ A column with a numpy dtype.
280
+
281
+ Returns
282
+ -------
283
+ pandas.Series
284
+ Integers and booleans in the pandas dtypes that accept missing values, Python objects
285
+ as guessed by ``infer_object_column``, any other column unchanged.
286
+
287
+ Examples
288
+ --------
289
+ >>> import pandas
290
+ >>> from numdaplot.tables.frames.frame_normalization import convert_numpy_column
291
+ >>> convert_numpy_column(pandas.Series([True, False])).dtype
292
+ BooleanDtype
293
+ """
294
+ dtype_kind = column.dtype.kind
295
+ if dtype_kind in INTEGER_KINDS:
296
+ integer_dtype = cast(numpy.dtype[Any], column.dtype)
297
+ integer_type = from_numpy_dtype(integer_dtype)
298
+ integer_column = convert_to_type(column, integer_type)
299
+ return integer_column
300
+
301
+ if dtype_kind == BOOLEAN_KIND:
302
+ boolean_column = convert_to_type(column, Type.BOOL)
303
+ return boolean_column
304
+
305
+ if column.dtype == PYTHON_OBJECT_DTYPE:
306
+ object_column = infer_object_column(column)
307
+ return object_column
308
+
309
+ return column
310
+
311
+
312
+ def infer_object_column(column: Column) -> Column:
313
+ """
314
+ Return a column of Python objects stored with the type its present values share.
315
+
316
+ .. versionadded:: 0.1.0
317
+
318
+ Parameters
319
+ ----------
320
+ column
321
+ A column of Python objects.
322
+
323
+ Returns
324
+ -------
325
+ pandas.Series
326
+ ``INT64`` when every present value is an integer, ``FLOAT64`` for decimals or integers and decimals,
327
+ ``BOOL`` for booleans, ``DATE`` for dates, ``DATETIME`` for datetimes or dates and datetimes, ``DURATION``
328
+ for durations, and ``TEXT`` for anything else, each value then written as a text.
329
+
330
+ Examples
331
+ --------
332
+ >>> import pandas
333
+ >>> from numdaplot.tables.frames.frame_normalization import infer_object_column
334
+ >>> infer_object_column(pandas.Series([1, None, 3], dtype=object)).tolist()
335
+ [1, <NA>, 3]
336
+ """
337
+ object_values = read_object_values(column)
338
+ if holds_only_times(object_values):
339
+ time_column = store_time_column(column)
340
+ return time_column
341
+
342
+ inferred_kind = infer_dtype(column, skipna=True)
343
+ target_type = INFERRED_TYPES.get(inferred_kind, Type.TEXT)
344
+ if inferred_kind in MOMENT_KINDS:
345
+ target_type = find_moment_type(column)
346
+
347
+ converted_column = convert_to_type(column, target_type)
348
+
349
+ return converted_column
350
+
351
+
352
+ def find_moment_type(column: Column) -> Type:
353
+ """
354
+ Return the type of a column of Python dates and datetimes.
355
+
356
+ .. versionadded:: 0.1.0
357
+
358
+ Parameters
359
+ ----------
360
+ column
361
+ A column of Python objects, each present value being a date or a datetime.
362
+
363
+ Returns
364
+ -------
365
+ Type
366
+ ``DATE`` for dates only, ``DATETIME`` as soon as a value is a datetime, a date then counting as midnight,
367
+ and ``TEXT`` as soon as a datetime has a time zone, as a column holds a single zone.
368
+
369
+ Examples
370
+ --------
371
+ >>> from datetime import date, datetime
372
+ >>> import pandas
373
+ >>> from numdaplot.tables.frames.frame_normalization import find_moment_type
374
+ >>> find_moment_type(pandas.Series([date(2026, 1, 31)], dtype=object))
375
+ <Type.DATE: 14>
376
+ >>> find_moment_type(pandas.Series([date(2026, 1, 31), datetime(2026, 1, 31, 8)], dtype=object))
377
+ <Type.DATETIME: 15>
378
+ """
379
+ present_column = column.dropna()
380
+ moments = present_column.tolist()
381
+ moment_type = Type.DATE
382
+
383
+ for moment in moments:
384
+ if isinstance(moment, datetime):
385
+ moment_type = Type.DATETIME
386
+ if moment.tzinfo is not None:
387
+ return Type.TEXT
388
+
389
+ return moment_type
390
+
391
+
392
+ def normalize_categories(column: Column) -> Column:
393
+ """
394
+ Return a column whose categories, if it has any, are texts.
395
+
396
+ .. versionadded:: 0.1.0
397
+
398
+ Parameters
399
+ ----------
400
+ column
401
+ A column stored with a dtype a Table uses.
402
+
403
+ Returns
404
+ -------
405
+ pandas.Series
406
+ The column itself, or a category column of texts when its categories are other values.
407
+
408
+ Examples
409
+ --------
410
+ >>> import pandas
411
+ >>> from numdaplot.tables.frames.frame_normalization import normalize_categories
412
+ >>> categories = normalize_categories(pandas.Series([1, 2], dtype="category"))
413
+ >>> categories.tolist()
414
+ ['1', '2']
415
+ """
416
+ if not isinstance(column.dtype, pandas.CategoricalDtype):
417
+ return column
418
+
419
+ categories = column.cat.categories
420
+ categories_kind = infer_dtype(categories, skipna=True)
421
+ if categories_kind in TEXT_INFERRED_KINDS:
422
+ return column
423
+
424
+ text_column = convert_to_type(column, Type.TEXT)
425
+ category_column = convert_to_type(text_column, Type.CATEGORY)
426
+
427
+ return category_column
428
+
429
+
430
+ def convert_to_type(column: Column, data_type: Type) -> Column:
431
+ """
432
+ Return a column converted to the pandas dtype of a numdaplot type.
433
+
434
+ .. versionadded:: 0.1.0
435
+
436
+ Parameters
437
+ ----------
438
+ column
439
+ Any column.
440
+ data_type
441
+ The numdaplot type to store the column as.
442
+
443
+ Returns
444
+ -------
445
+ pandas.Series
446
+ The converted column.
447
+
448
+ Examples
449
+ --------
450
+ >>> import pandas
451
+ >>> import numdaplot as ndp
452
+ >>> from numdaplot.tables.frames.frame_normalization import convert_to_type
453
+ >>> convert_to_type(pandas.Series([1, 2]), ndp.Type.TEXT).tolist()
454
+ ['1', '2']
455
+ """
456
+ pandas_dtype = to_pandas_dtype(data_type)
457
+ converted_column = column.astype(pandas_dtype)
458
+
459
+ return converted_column
@@ -0,0 +1,85 @@
1
+ """
2
+ Name of the Table column in the type errors of a block.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from types import TracebackType
8
+
9
+ from numdaplot.errors.incompatible_types_error import IncompatibleTypesError
10
+ from numdaplot.errors.time_overflow_error import TimeOverflowError
11
+ from numdaplot.errors.value_conversion_error import ValueConversionError
12
+ from numdaplot.tables.frames.column import Column
13
+
14
+
15
+ class NamedColumnErrors:
16
+ """
17
+ Context adding the name of a Table column to the type errors raised by a block.
18
+
19
+ .. versionadded:: 0.1.0
20
+
21
+ Parameters
22
+ ----------
23
+ column
24
+ The column the block works on. A column without name leaves the errors as they are.
25
+
26
+ Examples
27
+ --------
28
+ >>> import pandas
29
+ >>> import numdaplot as ndp
30
+ >>> from numdaplot.tables.frames.named_column_errors import NamedColumnErrors
31
+ >>> try:
32
+ ... with NamedColumnErrors(pandas.Series([1.0], name="price")):
33
+ ... raise ndp.IncompatibleTypesError("Contains", ["FLOAT64"])
34
+ ... except ndp.IncompatibleTypesError as error:
35
+ ... print(error)
36
+ Cannot apply Contains to the FLOAT64 column 'price'.
37
+ """
38
+
39
+ def __init__(self, column: Column) -> None:
40
+ """
41
+ Keep the column of the block.
42
+
43
+ .. versionadded:: 0.1.0
44
+
45
+ Parameters
46
+ ----------
47
+ column
48
+ The column the block works on.
49
+ """
50
+ self.column = column
51
+
52
+ def __enter__(self) -> None:
53
+ """
54
+ Start the block.
55
+
56
+ .. versionadded:: 0.1.0
57
+ """
58
+
59
+ def __exit__(
60
+ self,
61
+ error_type: type[BaseException] | None,
62
+ error: BaseException | None,
63
+ traceback: TracebackType | None,
64
+ ) -> None:
65
+ """
66
+ Name the column in a type error of the block, which then goes on.
67
+
68
+ .. versionadded:: 0.1.0
69
+
70
+ Parameters
71
+ ----------
72
+ error_type
73
+ The type of the error raised by the block, or None.
74
+ error
75
+ The error raised by the block, or None.
76
+ traceback
77
+ Its traceback, or None.
78
+ """
79
+ column_name = self.column.name
80
+ if column_name is None:
81
+ return
82
+
83
+ if isinstance(error, IncompatibleTypesError | TimeOverflowError | ValueConversionError):
84
+ column_text = str(column_name)
85
+ error.name_column(column_text)
@@ -0,0 +1,113 @@
1
+ """
2
+ Exact reading of decimals written as texts, which pandas only gives by default from version 3.1.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ import re
8
+ from typing import Any, cast
9
+
10
+ import numpy
11
+ import pandas
12
+ from numpy.typing import NDArray
13
+
14
+ VERSION_PATTERN = r"(\d+)\.(\d+)"
15
+ FIRST_EXACT_VERSION = (3, 1)
16
+ FLOAT_PRECISION_SETTING = "float_precision"
17
+ ROUND_TRIP_PRECISION = "round_trip"
18
+ DECIMAL_KIND = "f"
19
+
20
+
21
+ def reads_exact_decimals(pandas_version: str) -> bool:
22
+ """
23
+ Return whether a version of pandas reads the exact value of a decimal written as a text.
24
+
25
+ .. versionadded:: 0.1.0
26
+
27
+ Parameters
28
+ ----------
29
+ pandas_version
30
+ The version, such as ``"3.1.0"``.
31
+
32
+ Returns
33
+ -------
34
+ bool
35
+ True from version 3.1.
36
+
37
+ Examples
38
+ --------
39
+ >>> from numdaplot.tables.frames.pandas_decimals import reads_exact_decimals
40
+ >>> reads_exact_decimals("2.3.0"), reads_exact_decimals("3.1.0rc0")
41
+ (False, True)
42
+ """
43
+ version_match = cast(re.Match[str], re.match(VERSION_PATTERN, pandas_version))
44
+ major_text, minor_text = version_match.groups()
45
+ major = int(major_text)
46
+ minor = int(minor_text)
47
+ is_exact = (major, minor) >= FIRST_EXACT_VERSION
48
+
49
+ return is_exact
50
+
51
+
52
+ READS_EXACT_DECIMALS = reads_exact_decimals(pandas.__version__)
53
+
54
+
55
+ def find_exact_csv_settings() -> dict[str, str]:
56
+ """
57
+ Return the settings ``pandas.read_csv`` needs to read the exact value of each decimal.
58
+
59
+ .. versionadded:: 0.1.0
60
+
61
+ Returns
62
+ -------
63
+ dict[str, str]
64
+ The precision of the slower exact reading before pandas 3.1, nothing from then on as the setting is
65
+ deprecated there.
66
+
67
+ Examples
68
+ --------
69
+ >>> from numdaplot.tables.frames.pandas_decimals import find_exact_csv_settings
70
+ >>> settings = find_exact_csv_settings()
71
+ >>> settings in ({}, {"float_precision": "round_trip"})
72
+ True
73
+ """
74
+ if READS_EXACT_DECIMALS:
75
+ return {}
76
+
77
+ return {FLOAT_PRECISION_SETTING: ROUND_TRIP_PRECISION}
78
+
79
+
80
+ def restore_exact_decimals(texts: NDArray[Any], numbers: NDArray[Any]) -> NDArray[Any]:
81
+ """
82
+ Return numbers read by ``pandas.to_numeric``, with the exact value of their texts before pandas 3.1.
83
+
84
+ .. versionadded:: 0.1.0
85
+
86
+ Parameters
87
+ ----------
88
+ texts
89
+ The texts holding the numbers, each one read by pandas without failure.
90
+ numbers
91
+ The numbers pandas read.
92
+
93
+ Returns
94
+ -------
95
+ NDArray
96
+ The exact decimals, or the numbers themselves when pandas read them exactly or read integers.
97
+
98
+ Examples
99
+ --------
100
+ >>> import numpy
101
+ >>> from numdaplot.tables.frames.pandas_decimals import restore_exact_decimals
102
+ >>> texts = numpy.array(["0.5"], dtype=object)
103
+ >>> restore_exact_decimals(texts, numpy.array([0.5]))
104
+ array([0.5])
105
+ """
106
+ if READS_EXACT_DECIMALS or numbers.dtype.kind != DECIMAL_KIND:
107
+ return numbers
108
+
109
+ text_list = cast(list[str], texts.tolist())
110
+ exact_list = [float(text) for text in text_list]
111
+ exact_numbers = numpy.array(exact_list, dtype=numbers.dtype)
112
+
113
+ return exact_numbers