fg-data-profiling 4.19.0__py2.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 (238) hide show
  1. data_profiling/__init__.py +34 -0
  2. data_profiling/compare_reports.py +359 -0
  3. data_profiling/config.py +496 -0
  4. data_profiling/config_default.yaml +223 -0
  5. data_profiling/config_minimal.yaml +222 -0
  6. data_profiling/controller/__init__.py +1 -0
  7. data_profiling/controller/console.py +125 -0
  8. data_profiling/controller/pandas_decorator.py +21 -0
  9. data_profiling/expectations_report.py +117 -0
  10. data_profiling/model/__init__.py +4 -0
  11. data_profiling/model/alerts.py +780 -0
  12. data_profiling/model/correlations.py +163 -0
  13. data_profiling/model/dataframe.py +35 -0
  14. data_profiling/model/describe.py +210 -0
  15. data_profiling/model/description.py +108 -0
  16. data_profiling/model/duplicates.py +14 -0
  17. data_profiling/model/expectation_algorithms.py +112 -0
  18. data_profiling/model/handler.py +81 -0
  19. data_profiling/model/missing.py +146 -0
  20. data_profiling/model/pairwise.py +33 -0
  21. data_profiling/model/pandas/__init__.py +55 -0
  22. data_profiling/model/pandas/correlations_pandas.py +207 -0
  23. data_profiling/model/pandas/dataframe_pandas.py +26 -0
  24. data_profiling/model/pandas/describe_boolean_pandas.py +43 -0
  25. data_profiling/model/pandas/describe_categorical_pandas.py +274 -0
  26. data_profiling/model/pandas/describe_counts_pandas.py +63 -0
  27. data_profiling/model/pandas/describe_date_pandas.py +77 -0
  28. data_profiling/model/pandas/describe_file_pandas.py +56 -0
  29. data_profiling/model/pandas/describe_generic_pandas.py +36 -0
  30. data_profiling/model/pandas/describe_image_pandas.py +255 -0
  31. data_profiling/model/pandas/describe_numeric_pandas.py +175 -0
  32. data_profiling/model/pandas/describe_path_pandas.py +63 -0
  33. data_profiling/model/pandas/describe_supported_pandas.py +41 -0
  34. data_profiling/model/pandas/describe_text_pandas.py +62 -0
  35. data_profiling/model/pandas/describe_timeseries_pandas.py +222 -0
  36. data_profiling/model/pandas/describe_url_pandas.py +57 -0
  37. data_profiling/model/pandas/discretize_pandas.py +81 -0
  38. data_profiling/model/pandas/duplicates_pandas.py +56 -0
  39. data_profiling/model/pandas/imbalance_pandas.py +35 -0
  40. data_profiling/model/pandas/missing_pandas.py +42 -0
  41. data_profiling/model/pandas/sample_pandas.py +38 -0
  42. data_profiling/model/pandas/summary_pandas.py +101 -0
  43. data_profiling/model/pandas/table_pandas.py +56 -0
  44. data_profiling/model/pandas/timeseries_index_pandas.py +33 -0
  45. data_profiling/model/pandas/utils_pandas.py +27 -0
  46. data_profiling/model/sample.py +37 -0
  47. data_profiling/model/spark/__init__.py +48 -0
  48. data_profiling/model/spark/correlations_spark.py +152 -0
  49. data_profiling/model/spark/dataframe_spark.py +34 -0
  50. data_profiling/model/spark/describe_boolean_spark.py +27 -0
  51. data_profiling/model/spark/describe_categorical_spark.py +28 -0
  52. data_profiling/model/spark/describe_counts_spark.py +105 -0
  53. data_profiling/model/spark/describe_date_spark.py +51 -0
  54. data_profiling/model/spark/describe_generic_spark.py +30 -0
  55. data_profiling/model/spark/describe_numeric_spark.py +155 -0
  56. data_profiling/model/spark/describe_supported_spark.py +33 -0
  57. data_profiling/model/spark/describe_text_spark.py +25 -0
  58. data_profiling/model/spark/duplicates_spark.py +54 -0
  59. data_profiling/model/spark/missing_spark.py +96 -0
  60. data_profiling/model/spark/sample_spark.py +43 -0
  61. data_profiling/model/spark/summary_spark.py +95 -0
  62. data_profiling/model/spark/table_spark.py +58 -0
  63. data_profiling/model/spark/timeseries_index_spark.py +12 -0
  64. data_profiling/model/summarizer.py +207 -0
  65. data_profiling/model/summary.py +66 -0
  66. data_profiling/model/summary_algorithms.py +276 -0
  67. data_profiling/model/table.py +10 -0
  68. data_profiling/model/timeseries_index.py +16 -0
  69. data_profiling/model/typeset.py +365 -0
  70. data_profiling/model/typeset_relations.py +143 -0
  71. data_profiling/profile_report.py +573 -0
  72. data_profiling/report/__init__.py +4 -0
  73. data_profiling/report/formatters.py +346 -0
  74. data_profiling/report/presentation/__init__.py +1 -0
  75. data_profiling/report/presentation/core/__init__.py +39 -0
  76. data_profiling/report/presentation/core/alerts.py +18 -0
  77. data_profiling/report/presentation/core/collapse.py +24 -0
  78. data_profiling/report/presentation/core/container.py +50 -0
  79. data_profiling/report/presentation/core/correlation_table.py +21 -0
  80. data_profiling/report/presentation/core/dropdown.py +44 -0
  81. data_profiling/report/presentation/core/duplicate.py +16 -0
  82. data_profiling/report/presentation/core/frequency_table.py +14 -0
  83. data_profiling/report/presentation/core/frequency_table_small.py +16 -0
  84. data_profiling/report/presentation/core/html.py +14 -0
  85. data_profiling/report/presentation/core/image.py +34 -0
  86. data_profiling/report/presentation/core/item_renderer.py +17 -0
  87. data_profiling/report/presentation/core/renderable.py +42 -0
  88. data_profiling/report/presentation/core/root.py +35 -0
  89. data_profiling/report/presentation/core/sample.py +20 -0
  90. data_profiling/report/presentation/core/scores.py +32 -0
  91. data_profiling/report/presentation/core/table.py +26 -0
  92. data_profiling/report/presentation/core/toggle_button.py +14 -0
  93. data_profiling/report/presentation/core/variable.py +40 -0
  94. data_profiling/report/presentation/core/variable_info.py +36 -0
  95. data_profiling/report/presentation/flavours/__init__.py +9 -0
  96. data_profiling/report/presentation/flavours/flavour_html.py +64 -0
  97. data_profiling/report/presentation/flavours/flavour_widget.py +61 -0
  98. data_profiling/report/presentation/flavours/flavours.py +43 -0
  99. data_profiling/report/presentation/flavours/html/__init__.py +47 -0
  100. data_profiling/report/presentation/flavours/html/alerts.py +10 -0
  101. data_profiling/report/presentation/flavours/html/collapse.py +7 -0
  102. data_profiling/report/presentation/flavours/html/container.py +58 -0
  103. data_profiling/report/presentation/flavours/html/correlation_table.py +13 -0
  104. data_profiling/report/presentation/flavours/html/dropdown.py +7 -0
  105. data_profiling/report/presentation/flavours/html/duplicate.py +24 -0
  106. data_profiling/report/presentation/flavours/html/frequency_table.py +20 -0
  107. data_profiling/report/presentation/flavours/html/frequency_table_small.py +15 -0
  108. data_profiling/report/presentation/flavours/html/html.py +6 -0
  109. data_profiling/report/presentation/flavours/html/image.py +7 -0
  110. data_profiling/report/presentation/flavours/html/root.py +14 -0
  111. data_profiling/report/presentation/flavours/html/sample.py +12 -0
  112. data_profiling/report/presentation/flavours/html/scores.py +11 -0
  113. data_profiling/report/presentation/flavours/html/table.py +7 -0
  114. data_profiling/report/presentation/flavours/html/templates/alerts/alert_constant.html +1 -0
  115. data_profiling/report/presentation/flavours/html/templates/alerts/alert_constant_length.html +1 -0
  116. data_profiling/report/presentation/flavours/html/templates/alerts/alert_dirty_category.html +1 -0
  117. data_profiling/report/presentation/flavours/html/templates/alerts/alert_duplicates.html +1 -0
  118. data_profiling/report/presentation/flavours/html/templates/alerts/alert_empty.html +1 -0
  119. data_profiling/report/presentation/flavours/html/templates/alerts/alert_high_cardinality.html +1 -0
  120. data_profiling/report/presentation/flavours/html/templates/alerts/alert_high_correlation.html +4 -0
  121. data_profiling/report/presentation/flavours/html/templates/alerts/alert_imbalance.html +1 -0
  122. data_profiling/report/presentation/flavours/html/templates/alerts/alert_infinite.html +1 -0
  123. data_profiling/report/presentation/flavours/html/templates/alerts/alert_missing.html +1 -0
  124. data_profiling/report/presentation/flavours/html/templates/alerts/alert_near_duplicates.html +1 -0
  125. data_profiling/report/presentation/flavours/html/templates/alerts/alert_non_stationary.html +1 -0
  126. data_profiling/report/presentation/flavours/html/templates/alerts/alert_seasonal.html +1 -0
  127. data_profiling/report/presentation/flavours/html/templates/alerts/alert_skewed.html +1 -0
  128. data_profiling/report/presentation/flavours/html/templates/alerts/alert_truncated.html +1 -0
  129. data_profiling/report/presentation/flavours/html/templates/alerts/alert_type_date.html +1 -0
  130. data_profiling/report/presentation/flavours/html/templates/alerts/alert_uniform.html +1 -0
  131. data_profiling/report/presentation/flavours/html/templates/alerts/alert_unique.html +1 -0
  132. data_profiling/report/presentation/flavours/html/templates/alerts/alert_unsupported.html +1 -0
  133. data_profiling/report/presentation/flavours/html/templates/alerts/alert_zeros.html +1 -0
  134. data_profiling/report/presentation/flavours/html/templates/alerts.html +47 -0
  135. data_profiling/report/presentation/flavours/html/templates/collapse.html +11 -0
  136. data_profiling/report/presentation/flavours/html/templates/correlation_table.html +5 -0
  137. data_profiling/report/presentation/flavours/html/templates/diagram.html +11 -0
  138. data_profiling/report/presentation/flavours/html/templates/dropdown.html +16 -0
  139. data_profiling/report/presentation/flavours/html/templates/duplicate.html +5 -0
  140. data_profiling/report/presentation/flavours/html/templates/frequency_table.html +45 -0
  141. data_profiling/report/presentation/flavours/html/templates/frequency_table_small.html +34 -0
  142. data_profiling/report/presentation/flavours/html/templates/report.html +26 -0
  143. data_profiling/report/presentation/flavours/html/templates/sample.html +10 -0
  144. data_profiling/report/presentation/flavours/html/templates/scores.html +78 -0
  145. data_profiling/report/presentation/flavours/html/templates/sequence/batch_grid.html +16 -0
  146. data_profiling/report/presentation/flavours/html/templates/sequence/grid.html +18 -0
  147. data_profiling/report/presentation/flavours/html/templates/sequence/list.html +7 -0
  148. data_profiling/report/presentation/flavours/html/templates/sequence/named_list.html +8 -0
  149. data_profiling/report/presentation/flavours/html/templates/sequence/overview_tabs.html +30 -0
  150. data_profiling/report/presentation/flavours/html/templates/sequence/scores.html +3 -0
  151. data_profiling/report/presentation/flavours/html/templates/sequence/sections.html +13 -0
  152. data_profiling/report/presentation/flavours/html/templates/sequence/select.html +40 -0
  153. data_profiling/report/presentation/flavours/html/templates/sequence/tabs.html +30 -0
  154. data_profiling/report/presentation/flavours/html/templates/table.html +38 -0
  155. data_profiling/report/presentation/flavours/html/templates/toggle_button.html +18 -0
  156. data_profiling/report/presentation/flavours/html/templates/variable.html +7 -0
  157. data_profiling/report/presentation/flavours/html/templates/variable_info.html +49 -0
  158. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/bootstrap.bundle.min.js +7 -0
  159. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/bootstrap.min.css +6 -0
  160. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/cosmo.bootstrap.min.css +12 -0
  161. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/flatly.bootstrap.min.css +12 -0
  162. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/script.js +52 -0
  163. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/simplex.bootstrap.min.css +12 -0
  164. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/style.css +253 -0
  165. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/united.bootstrap.min.css +12 -0
  166. data_profiling/report/presentation/flavours/html/templates/wrapper/footer.html +7 -0
  167. data_profiling/report/presentation/flavours/html/templates/wrapper/javascript.html +18 -0
  168. data_profiling/report/presentation/flavours/html/templates/wrapper/navigation.html +36 -0
  169. data_profiling/report/presentation/flavours/html/templates/wrapper/style.html +53 -0
  170. data_profiling/report/presentation/flavours/html/templates.py +76 -0
  171. data_profiling/report/presentation/flavours/html/toggle_button.py +7 -0
  172. data_profiling/report/presentation/flavours/html/variable.py +7 -0
  173. data_profiling/report/presentation/flavours/html/variable_info.py +7 -0
  174. data_profiling/report/presentation/flavours/widget/__init__.py +49 -0
  175. data_profiling/report/presentation/flavours/widget/alerts.py +45 -0
  176. data_profiling/report/presentation/flavours/widget/collapse.py +43 -0
  177. data_profiling/report/presentation/flavours/widget/container.py +121 -0
  178. data_profiling/report/presentation/flavours/widget/correlation_table.py +14 -0
  179. data_profiling/report/presentation/flavours/widget/dropdown.py +31 -0
  180. data_profiling/report/presentation/flavours/widget/duplicate.py +14 -0
  181. data_profiling/report/presentation/flavours/widget/frequency_table.py +57 -0
  182. data_profiling/report/presentation/flavours/widget/frequency_table_small.py +66 -0
  183. data_profiling/report/presentation/flavours/widget/html.py +11 -0
  184. data_profiling/report/presentation/flavours/widget/image.py +26 -0
  185. data_profiling/report/presentation/flavours/widget/notebook.py +81 -0
  186. data_profiling/report/presentation/flavours/widget/root.py +10 -0
  187. data_profiling/report/presentation/flavours/widget/sample.py +14 -0
  188. data_profiling/report/presentation/flavours/widget/table.py +30 -0
  189. data_profiling/report/presentation/flavours/widget/toggle_button.py +17 -0
  190. data_profiling/report/presentation/flavours/widget/variable.py +12 -0
  191. data_profiling/report/presentation/flavours/widget/variable_info.py +11 -0
  192. data_profiling/report/presentation/frequency_table_utils.py +141 -0
  193. data_profiling/report/structure/__init__.py +1 -0
  194. data_profiling/report/structure/correlations.py +123 -0
  195. data_profiling/report/structure/overview.py +376 -0
  196. data_profiling/report/structure/report.py +457 -0
  197. data_profiling/report/structure/variables/__init__.py +35 -0
  198. data_profiling/report/structure/variables/render_boolean.py +132 -0
  199. data_profiling/report/structure/variables/render_categorical.py +566 -0
  200. data_profiling/report/structure/variables/render_common.py +31 -0
  201. data_profiling/report/structure/variables/render_complex.py +102 -0
  202. data_profiling/report/structure/variables/render_count.py +172 -0
  203. data_profiling/report/structure/variables/render_date.py +143 -0
  204. data_profiling/report/structure/variables/render_file.py +70 -0
  205. data_profiling/report/structure/variables/render_generic.py +45 -0
  206. data_profiling/report/structure/variables/render_image.py +204 -0
  207. data_profiling/report/structure/variables/render_path.py +134 -0
  208. data_profiling/report/structure/variables/render_real.py +314 -0
  209. data_profiling/report/structure/variables/render_text.py +189 -0
  210. data_profiling/report/structure/variables/render_timeseries.py +371 -0
  211. data_profiling/report/structure/variables/render_url.py +132 -0
  212. data_profiling/report/utils.py +34 -0
  213. data_profiling/serialize_report.py +143 -0
  214. data_profiling/utils/__init__.py +1 -0
  215. data_profiling/utils/backend.py +9 -0
  216. data_profiling/utils/cache.py +59 -0
  217. data_profiling/utils/common.py +142 -0
  218. data_profiling/utils/compat.py +31 -0
  219. data_profiling/utils/dataframe.py +238 -0
  220. data_profiling/utils/logger.py +53 -0
  221. data_profiling/utils/notebook.py +8 -0
  222. data_profiling/utils/paths.py +45 -0
  223. data_profiling/utils/progress_bar.py +15 -0
  224. data_profiling/utils/styles.py +22 -0
  225. data_profiling/utils/versions.py +19 -0
  226. data_profiling/version.py +1 -0
  227. data_profiling/visualisation/__init__.py +1 -0
  228. data_profiling/visualisation/context.py +87 -0
  229. data_profiling/visualisation/missing.py +138 -0
  230. data_profiling/visualisation/plot.py +1158 -0
  231. data_profiling/visualisation/utils.py +113 -0
  232. fg_data_profiling-4.19.0.dist-info/METADATA +362 -0
  233. fg_data_profiling-4.19.0.dist-info/RECORD +238 -0
  234. fg_data_profiling-4.19.0.dist-info/WHEEL +6 -0
  235. fg_data_profiling-4.19.0.dist-info/entry_points.txt +3 -0
  236. fg_data_profiling-4.19.0.dist-info/licenses/LICENSE +21 -0
  237. fg_data_profiling-4.19.0.dist-info/top_level.txt +2 -0
  238. ydata_profiling/__init__.py +43 -0
@@ -0,0 +1,134 @@
1
+ from data_profiling.config import Settings
2
+ from data_profiling.report.formatters import fmt, fmt_numeric
3
+ from data_profiling.report.presentation.core import Container, FrequencyTable, Table
4
+ from data_profiling.report.presentation.frequency_table_utils import freq_table
5
+ from data_profiling.report.structure.variables.render_categorical import (
6
+ render_categorical,
7
+ )
8
+
9
+
10
+ def render_path(config: Settings, summary: dict) -> dict:
11
+ varid = summary["varid"]
12
+ n_freq_table_max = config.n_freq_table_max
13
+ redact = config.vars.cat.redact
14
+
15
+ template_variables = render_categorical(config, summary)
16
+
17
+ keys = ["name", "parent", "suffix", "stem", "anchor"]
18
+ for path_part in keys:
19
+ template_variables[f"freqtable_{path_part}"] = freq_table(
20
+ freqtable=summary[f"{path_part}_counts"],
21
+ n=summary["n"],
22
+ max_number_to_print=n_freq_table_max,
23
+ )
24
+
25
+ # Top
26
+ template_variables["top"].content["items"][0].content["var_type"] = "Path"
27
+
28
+ # Bottom
29
+ path_overview_tab = Container(
30
+ [
31
+ Table(
32
+ [
33
+ {
34
+ "name": "Common prefix",
35
+ "value": fmt(summary["common_prefix"]),
36
+ "alert": False,
37
+ },
38
+ {
39
+ "name": "Unique stems",
40
+ "value": fmt_numeric(
41
+ summary["n_stem_unique"], precision=config.report.precision
42
+ ),
43
+ "alert": False,
44
+ },
45
+ {
46
+ "name": "Unique names",
47
+ "value": fmt_numeric(
48
+ summary["n_name_unique"], precision=config.report.precision
49
+ ),
50
+ "alert": False,
51
+ },
52
+ {
53
+ "name": "Unique extensions",
54
+ "value": fmt_numeric(
55
+ summary["n_suffix_unique"],
56
+ precision=config.report.precision,
57
+ ),
58
+ "alert": False,
59
+ },
60
+ {
61
+ "name": "Unique directories",
62
+ "value": fmt_numeric(
63
+ summary["n_parent_unique"],
64
+ precision=config.report.precision,
65
+ ),
66
+ "alert": False,
67
+ },
68
+ {
69
+ "name": "Unique anchors",
70
+ "value": fmt_numeric(
71
+ summary["n_anchor_unique"],
72
+ precision=config.report.precision,
73
+ ),
74
+ "alert": False,
75
+ },
76
+ ],
77
+ style=config.html.style,
78
+ )
79
+ ],
80
+ anchor_id=f"{varid}tbl",
81
+ name="Overview",
82
+ sequence_type="list",
83
+ )
84
+
85
+ path_items = [
86
+ path_overview_tab,
87
+ FrequencyTable(
88
+ template_variables["freq_table_rows"],
89
+ name="Full",
90
+ anchor_id=f"{varid}full_frequency",
91
+ redact=redact,
92
+ ),
93
+ FrequencyTable(
94
+ template_variables["freqtable_stem"],
95
+ name="Stem",
96
+ anchor_id=f"{varid}stem_frequency",
97
+ redact=redact,
98
+ ),
99
+ FrequencyTable(
100
+ template_variables["freqtable_name"],
101
+ name="Name",
102
+ anchor_id=f"{varid}name_frequency",
103
+ redact=redact,
104
+ ),
105
+ FrequencyTable(
106
+ template_variables["freqtable_suffix"],
107
+ name="Extension",
108
+ anchor_id=f"{varid}suffix_frequency",
109
+ redact=redact,
110
+ ),
111
+ FrequencyTable(
112
+ template_variables["freqtable_parent"],
113
+ name="Parent",
114
+ anchor_id=f"{varid}parent_frequency",
115
+ redact=redact,
116
+ ),
117
+ FrequencyTable(
118
+ template_variables["freqtable_anchor"],
119
+ name="Anchor",
120
+ anchor_id=f"{varid}anchor_frequency",
121
+ redact=redact,
122
+ ),
123
+ ]
124
+
125
+ path_tab = Container(
126
+ path_items,
127
+ name="Path",
128
+ sequence_type="tabs",
129
+ anchor_id=f"{varid}path",
130
+ )
131
+
132
+ template_variables["bottom"].content["items"].append(path_tab)
133
+
134
+ return template_variables
@@ -0,0 +1,314 @@
1
+ from data_profiling.config import Settings
2
+ from data_profiling.report.formatters import (
3
+ fmt,
4
+ fmt_bytesize,
5
+ fmt_monotonic,
6
+ fmt_numeric,
7
+ fmt_percent,
8
+ )
9
+ from data_profiling.report.presentation.core import (
10
+ Container,
11
+ FrequencyTable,
12
+ Table,
13
+ VariableInfo,
14
+ )
15
+ from data_profiling.report.structure.variables.render_common import render_common
16
+ from data_profiling.report.utils import image_or_empty
17
+ from data_profiling.visualisation.plot import histogram, mini_histogram
18
+
19
+
20
+ def render_real(config: Settings, summary: dict) -> dict:
21
+ varid = summary["varid"]
22
+ template_variables = render_common(config, summary)
23
+ image_format = config.plot.image_format
24
+
25
+ name = "Real number (ℝ)"
26
+
27
+ # Top
28
+ info = VariableInfo(
29
+ summary["varid"],
30
+ summary["varname"],
31
+ name,
32
+ summary["alerts"],
33
+ summary["description"],
34
+ style=config.html.style,
35
+ )
36
+
37
+ table1 = Table(
38
+ [
39
+ {
40
+ "name": "Distinct",
41
+ "value": fmt(summary["n_distinct"]),
42
+ "alert": "n_distinct" in summary["alert_fields"],
43
+ },
44
+ {
45
+ "name": "Distinct (%)",
46
+ "value": fmt_percent(summary["p_distinct"]),
47
+ "alert": "p_distinct" in summary["alert_fields"],
48
+ },
49
+ {
50
+ "name": "Missing",
51
+ "value": fmt(summary["n_missing"]),
52
+ "alert": "n_missing" in summary["alert_fields"],
53
+ },
54
+ {
55
+ "name": "Missing (%)",
56
+ "value": fmt_percent(summary["p_missing"]),
57
+ "alert": "p_missing" in summary["alert_fields"],
58
+ },
59
+ {
60
+ "name": "Infinite",
61
+ "value": fmt(summary["n_infinite"]),
62
+ "alert": "n_infinite" in summary["alert_fields"],
63
+ },
64
+ {
65
+ "name": "Infinite (%)",
66
+ "value": fmt_percent(summary["p_infinite"]),
67
+ "alert": "p_infinite" in summary["alert_fields"],
68
+ },
69
+ {
70
+ "name": "Mean",
71
+ "value": fmt_numeric(
72
+ summary["mean"], precision=config.report.precision
73
+ ),
74
+ "alert": False,
75
+ },
76
+ ],
77
+ style=config.html.style,
78
+ )
79
+
80
+ table2 = Table(
81
+ [
82
+ {
83
+ "name": "Minimum",
84
+ "value": fmt_numeric(summary["min"], precision=config.report.precision),
85
+ "alert": False,
86
+ },
87
+ {
88
+ "name": "Maximum",
89
+ "value": fmt_numeric(summary["max"], precision=config.report.precision),
90
+ "alert": False,
91
+ },
92
+ {
93
+ "name": "Zeros",
94
+ "value": fmt(summary["n_zeros"]),
95
+ "alert": "n_zeros" in summary["alert_fields"],
96
+ },
97
+ {
98
+ "name": "Zeros (%)",
99
+ "value": fmt_percent(summary["p_zeros"]),
100
+ "alert": "p_zeros" in summary["alert_fields"],
101
+ },
102
+ {
103
+ "name": "Negative",
104
+ "value": fmt(summary["n_negative"]),
105
+ "alert": False,
106
+ },
107
+ {
108
+ "name": "Negative (%)",
109
+ "value": fmt_percent(summary["p_negative"]),
110
+ "alert": False,
111
+ },
112
+ {
113
+ "name": "Memory size",
114
+ "value": fmt_bytesize(summary["memory_size"]),
115
+ "alert": False,
116
+ },
117
+ ],
118
+ style=config.html.style,
119
+ )
120
+
121
+ summary_histogram = summary.get("histogram", [])
122
+
123
+ mini_hist_data = None
124
+
125
+ if summary_histogram:
126
+ if isinstance(summary_histogram, list):
127
+ mini_hist_data = mini_histogram(
128
+ config,
129
+ [x[0] for x in summary_histogram],
130
+ [x[1] for x in summary_histogram],
131
+ )
132
+ else:
133
+ mini_hist_data = mini_histogram(config, *summary_histogram)
134
+
135
+ mini_histo = image_or_empty(
136
+ mini_hist_data,
137
+ alt="Mini histogram",
138
+ image_format=image_format,
139
+ name="Mini Histogram",
140
+ anchor_id=f"{varid}minihistogram",
141
+ )
142
+
143
+ template_variables["top"] = Container(
144
+ [info, table1, table2, mini_histo], sequence_type="grid"
145
+ )
146
+
147
+ quantile_statistics = Table(
148
+ [
149
+ {
150
+ "name": "Minimum",
151
+ "value": fmt_numeric(summary["min"], precision=config.report.precision),
152
+ },
153
+ {
154
+ "name": "5-th percentile",
155
+ "value": fmt_numeric(summary["5%"], precision=config.report.precision),
156
+ },
157
+ {
158
+ "name": "Q1",
159
+ "value": fmt_numeric(summary["25%"], precision=config.report.precision),
160
+ },
161
+ {
162
+ "name": "median",
163
+ "value": fmt_numeric(summary["50%"], precision=config.report.precision),
164
+ },
165
+ {
166
+ "name": "Q3",
167
+ "value": fmt_numeric(summary["75%"], precision=config.report.precision),
168
+ },
169
+ {
170
+ "name": "95-th percentile",
171
+ "value": fmt_numeric(summary["95%"], precision=config.report.precision),
172
+ },
173
+ {
174
+ "name": "Maximum",
175
+ "value": fmt_numeric(summary["max"], precision=config.report.precision),
176
+ },
177
+ {
178
+ "name": "Range",
179
+ "value": fmt_numeric(
180
+ summary["range"], precision=config.report.precision
181
+ ),
182
+ },
183
+ {
184
+ "name": "Interquartile range (IQR)",
185
+ "value": fmt_numeric(summary["iqr"], precision=config.report.precision),
186
+ },
187
+ ],
188
+ name="Quantile statistics",
189
+ style=config.html.style,
190
+ )
191
+
192
+ descriptive_statistics = Table(
193
+ [
194
+ {
195
+ "name": "Standard deviation",
196
+ "value": fmt_numeric(summary["std"], precision=config.report.precision),
197
+ },
198
+ {
199
+ "name": "Coefficient of variation (CV)",
200
+ "value": fmt_numeric(summary["cv"], precision=config.report.precision),
201
+ },
202
+ {
203
+ "name": "Kurtosis",
204
+ "value": fmt_numeric(
205
+ summary["kurtosis"], precision=config.report.precision
206
+ ),
207
+ },
208
+ {
209
+ "name": "Mean",
210
+ "value": fmt_numeric(
211
+ summary["mean"], precision=config.report.precision
212
+ ),
213
+ },
214
+ {
215
+ "name": "Median Absolute Deviation (MAD)",
216
+ "value": fmt_numeric(summary["mad"], precision=config.report.precision),
217
+ },
218
+ {
219
+ "name": "Skewness",
220
+ "value": fmt_numeric(
221
+ summary["skewness"], precision=config.report.precision
222
+ ),
223
+ "class": "alert" if "skewness" in summary["alert_fields"] else "",
224
+ },
225
+ {
226
+ "name": "Sum",
227
+ "value": fmt_numeric(summary["sum"], precision=config.report.precision),
228
+ },
229
+ {
230
+ "name": "Variance",
231
+ "value": fmt_numeric(
232
+ summary["variance"], precision=config.report.precision
233
+ ),
234
+ },
235
+ {
236
+ "name": "Monotonicity",
237
+ "value": fmt_monotonic(summary["monotonic"]),
238
+ },
239
+ ],
240
+ name="Descriptive statistics",
241
+ style=config.html.style,
242
+ )
243
+
244
+ statistics = Container(
245
+ [quantile_statistics, descriptive_statistics],
246
+ anchor_id=f"{varid}statistics",
247
+ name="Statistics",
248
+ sequence_type="grid",
249
+ )
250
+
251
+ hist_data = None
252
+ hist_caption = None
253
+
254
+ if summary_histogram:
255
+ if isinstance(summary_histogram, list):
256
+ hist_data = histogram(
257
+ config,
258
+ [x[0] for x in summary_histogram],
259
+ [x[1] for x in summary_histogram],
260
+ )
261
+ bins = len(summary_histogram[0][1])
262
+ hist_caption = (
263
+ f"<strong>Histogram with fixed size bins</strong> (bins={bins - 1})"
264
+ )
265
+ else:
266
+ hist_data = histogram(config, *summary_histogram)
267
+ hist_caption = (
268
+ f"<strong>Histogram with fixed size bins</strong> "
269
+ f"(bins={len(summary_histogram[1]) - 1})"
270
+ )
271
+
272
+ hist = image_or_empty(
273
+ hist_data,
274
+ alt="Histogram",
275
+ image_format=image_format,
276
+ caption=hist_caption,
277
+ name="Histogram",
278
+ anchor_id=f"{varid}histogram",
279
+ )
280
+
281
+ fq = FrequencyTable(
282
+ template_variables["freq_table_rows"],
283
+ name="Common values",
284
+ anchor_id=f"{varid}common_values",
285
+ redact=False,
286
+ )
287
+
288
+ evs = Container(
289
+ [
290
+ FrequencyTable(
291
+ template_variables["firstn_expanded"],
292
+ name=f"Minimum {config.n_extreme_obs} values",
293
+ anchor_id=f"{varid}firstn",
294
+ redact=False,
295
+ ),
296
+ FrequencyTable(
297
+ template_variables["lastn_expanded"],
298
+ name=f"Maximum {config.n_extreme_obs} values",
299
+ anchor_id=f"{varid}lastn",
300
+ redact=False,
301
+ ),
302
+ ],
303
+ sequence_type="tabs",
304
+ name="Extreme values",
305
+ anchor_id=f"{varid}extreme_values",
306
+ )
307
+
308
+ template_variables["bottom"] = Container(
309
+ [statistics, hist, fq, evs],
310
+ sequence_type="tabs",
311
+ anchor_id=f"{varid}bottom",
312
+ )
313
+
314
+ return template_variables
@@ -0,0 +1,189 @@
1
+ from typing import Any, Dict, List
2
+
3
+ from data_profiling.config import Settings
4
+ from data_profiling.report.formatters import fmt, fmt_bytesize, fmt_percent
5
+ from data_profiling.report.presentation.core import (
6
+ Container,
7
+ FrequencyTable,
8
+ Image,
9
+ Table,
10
+ )
11
+ from data_profiling.report.presentation.core.variable_info import VariableInfo
12
+ from data_profiling.report.structure.variables.render_categorical import (
13
+ _get_n,
14
+ freq_table,
15
+ render_categorical,
16
+ render_categorical_frequency,
17
+ render_categorical_length,
18
+ render_categorical_unicode,
19
+ )
20
+ from data_profiling.report.structure.variables.render_common import render_common
21
+ from data_profiling.visualisation.plot import plot_word_cloud
22
+
23
+
24
+ def render_text(config: Settings, summary: Dict[str, Any]) -> Dict[str, Any]:
25
+ if config.vars.text.redact:
26
+ render = render_categorical(config, summary)
27
+ return render
28
+
29
+ varid = summary["varid"]
30
+ words = config.vars.text.words
31
+ characters = config.vars.text.characters
32
+ length = config.vars.text.length
33
+
34
+ template_variables = render_common(config, summary)
35
+
36
+ top_items: List[Any] = []
37
+ var_info = VariableInfo(
38
+ anchor_id=varid,
39
+ var_name=summary["varname"],
40
+ var_type=summary["type"],
41
+ alerts=summary["alerts"],
42
+ description=summary["description"],
43
+ style=config.html.style,
44
+ )
45
+ top_items.append(var_info)
46
+
47
+ table = Table(
48
+ [
49
+ {
50
+ "name": "Distinct",
51
+ "value": fmt(summary["n_distinct"]),
52
+ "alert": "n_distinct" in summary["alert_fields"],
53
+ },
54
+ {
55
+ "name": "Distinct (%)",
56
+ "value": fmt_percent(summary["p_distinct"]),
57
+ "alert": "p_distinct" in summary["alert_fields"],
58
+ },
59
+ {
60
+ "name": "Missing",
61
+ "value": fmt(summary["n_missing"]),
62
+ "alert": "n_missing" in summary["alert_fields"],
63
+ },
64
+ {
65
+ "name": "Missing (%)",
66
+ "value": fmt_percent(summary["p_missing"]),
67
+ "alert": "p_missing" in summary["alert_fields"],
68
+ },
69
+ {
70
+ "name": "Memory size",
71
+ "value": fmt_bytesize(summary["memory_size"]),
72
+ "alert": False,
73
+ },
74
+ ],
75
+ style=config.html.style,
76
+ )
77
+ top_items.append(table)
78
+
79
+ if words and "word_counts" in summary:
80
+ mini_wordcloud = Image(
81
+ plot_word_cloud(config, summary["word_counts"]),
82
+ image_format=config.plot.image_format,
83
+ alt="Mini wordcloud",
84
+ )
85
+ top_items.append(mini_wordcloud)
86
+ template_variables["top"] = Container(top_items, sequence_type="grid")
87
+
88
+ # ============================================================================================
89
+
90
+ bottom_items = []
91
+ overview_items = []
92
+ # length isn't being computed for categorical in spark
93
+ if length and "max_length" in summary:
94
+ length_table, length_histo = render_categorical_length(config, summary, varid)
95
+ overview_items.append(length_table)
96
+
97
+ # characters isn't being computed for categorical in spark
98
+ unitab = None
99
+ if characters and "category_alias_counts" in summary:
100
+ overview_table_char, unitab = render_categorical_unicode(config, summary, varid)
101
+ overview_items.append(overview_table_char)
102
+
103
+ unique_stats = render_categorical_frequency(config, summary, varid)
104
+ overview_items.append(unique_stats)
105
+
106
+ if not config.vars.text.redact:
107
+ rows = ("1st row", "2nd row", "3rd row", "4th row", "5th row")
108
+
109
+ if isinstance(summary["first_rows"], list):
110
+ sample = Table(
111
+ [
112
+ {
113
+ "name": name,
114
+ "value": fmt(value),
115
+ "alert": False,
116
+ }
117
+ for name, *value in zip(rows, *summary["first_rows"])
118
+ ],
119
+ name="Sample",
120
+ style=config.html.style,
121
+ )
122
+ else:
123
+ sample = Table(
124
+ [
125
+ {
126
+ "name": name,
127
+ "value": fmt(value),
128
+ "alert": False,
129
+ }
130
+ for name, value in zip(rows, summary["first_rows"])
131
+ ],
132
+ name="Sample",
133
+ style=config.html.style,
134
+ )
135
+ overview_items.append(sample)
136
+ overview = Container(
137
+ overview_items,
138
+ name="Overview",
139
+ anchor_id=f"{varid}overview",
140
+ sequence_type="batch_grid",
141
+ batch_size=len(overview_items),
142
+ titles=False,
143
+ )
144
+ bottom_items.append(overview)
145
+
146
+ if words and "word_counts" in summary:
147
+ woc = freq_table(
148
+ freqtable=summary["word_counts"],
149
+ n=_get_n(summary["word_counts"]),
150
+ max_number_to_print=10,
151
+ )
152
+
153
+ fqwo = FrequencyTable(
154
+ woc,
155
+ name="Common words",
156
+ anchor_id=f"{varid}cwo",
157
+ redact=config.vars.text.redact,
158
+ )
159
+
160
+ image = Image(
161
+ plot_word_cloud(config, summary["word_counts"]),
162
+ image_format=config.plot.image_format,
163
+ alt="Wordcloud",
164
+ )
165
+
166
+ bottom_items.append(
167
+ Container(
168
+ [fqwo, image],
169
+ name="Words",
170
+ anchor_id=f"{varid}word",
171
+ sequence_type="grid",
172
+ )
173
+ )
174
+
175
+ if unitab is not None:
176
+ bottom_items.append(
177
+ Container(
178
+ [unitab],
179
+ name="Characters",
180
+ anchor_id=f"{varid}characters",
181
+ sequence_type="grid",
182
+ )
183
+ )
184
+
185
+ template_variables["bottom"] = Container(
186
+ bottom_items, sequence_type="tabs", anchor_id=f"{varid}bottom"
187
+ )
188
+
189
+ return template_variables