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,457 @@
1
+ import os
2
+ from typing import List, Sequence
3
+
4
+ import pandas as pd
5
+ from tqdm.auto import tqdm
6
+
7
+ from data_profiling.config import Settings
8
+ from data_profiling.model import BaseDescription
9
+ from data_profiling.model.alerts import AlertType
10
+ from data_profiling.model.handler import get_render_map
11
+ from data_profiling.report.presentation.core import (
12
+ HTML,
13
+ Collapse,
14
+ Container,
15
+ Dropdown,
16
+ Duplicate,
17
+ )
18
+ from data_profiling.report.presentation.core import Image as ImageWidget
19
+ from data_profiling.report.presentation.core import Sample, ToggleButton, Variable
20
+ from data_profiling.report.presentation.core.renderable import Renderable
21
+ from data_profiling.report.presentation.core.root import Root
22
+ from data_profiling.report.structure.correlations import get_correlation_items
23
+ from data_profiling.report.structure.overview import get_dataset_items
24
+ from data_profiling.utils.dataframe import slugify
25
+
26
+
27
+ def get_missing_items(config: Settings, summary: BaseDescription) -> list:
28
+ """Return the missing diagrams
29
+
30
+ Args:
31
+ config: report Settings object
32
+ summary: the dataframe summary
33
+
34
+ Returns:
35
+ A list with the missing diagrams
36
+ """
37
+ items = [
38
+ ImageWidget(
39
+ item["matrix"],
40
+ image_format=config.plot.image_format,
41
+ alt=item["name"],
42
+ name=item["name"],
43
+ anchor_id=key,
44
+ caption=item["caption"],
45
+ )
46
+ if isinstance(item["name"], str)
47
+ else Container(
48
+ [
49
+ ImageWidget(
50
+ item["matrix"][i],
51
+ image_format=config.plot.image_format,
52
+ alt=item["name"][i],
53
+ name=config.html.style._labels[i],
54
+ anchor_id=key,
55
+ caption=item["caption"][i],
56
+ )
57
+ for i in range(len(item["name"]))
58
+ ],
59
+ sequence_type="batch_grid",
60
+ batch_size=len(config.html.style._labels),
61
+ anchor_id=key,
62
+ name=item["name"][0],
63
+ )
64
+ for key, item in summary.missing.items()
65
+ ]
66
+
67
+ return items
68
+
69
+
70
+ def render_variables_section(
71
+ config: Settings, dataframe_summary: BaseDescription
72
+ ) -> list:
73
+ """Render the HTML for each of the variables in the DataFrame.
74
+
75
+ Args:
76
+ config: report Settings object
77
+ dataframe_summary: The statistics for each variable.
78
+
79
+ Returns:
80
+ The rendered HTML, where each row represents a variable.
81
+ """
82
+
83
+ templs = []
84
+
85
+ descriptions = config.variables.descriptions
86
+ show_description = config.show_variable_description
87
+ reject_variables = config.reject_variables
88
+
89
+ render_map = get_render_map()
90
+
91
+ for idx, summary in dataframe_summary.variables.items():
92
+ # Common template variables
93
+ if not isinstance(dataframe_summary.alerts, tuple):
94
+ alerts = [
95
+ alert.fmt()
96
+ for alert in dataframe_summary.alerts
97
+ if alert.column_name == idx
98
+ ]
99
+
100
+ alert_fields = {
101
+ field
102
+ for alert in dataframe_summary.alerts
103
+ if alert.column_name == idx
104
+ for field in alert.fields
105
+ }
106
+
107
+ alert_types = {
108
+ alert.alert_type
109
+ for alert in dataframe_summary.alerts
110
+ if alert.column_name == idx
111
+ }
112
+ else:
113
+ alerts = tuple(
114
+ [alert.fmt() for alert in summary_alerts if alert.column_name == idx]
115
+ for summary_alerts in dataframe_summary.alerts
116
+ ) # type: ignore
117
+
118
+ alert_fields = {
119
+ field
120
+ for summary_alerts in dataframe_summary.alerts
121
+ for alert in summary_alerts
122
+ if alert.column_name == idx
123
+ for field in alert.fields
124
+ }
125
+
126
+ alert_types = {
127
+ alert.alert_type
128
+ for summary_alerts in dataframe_summary.alerts
129
+ for alert in summary_alerts
130
+ if alert.column_name == idx
131
+ }
132
+
133
+ template_variables = {
134
+ "varname": idx,
135
+ "varid": hash(idx),
136
+ "alerts": alerts,
137
+ "description": descriptions.get(idx, "") if show_description else "",
138
+ "alert_fields": alert_fields,
139
+ }
140
+
141
+ template_variables.update(summary)
142
+
143
+ # Per type template variables
144
+ if isinstance(summary["type"], list):
145
+ types = set(summary["type"])
146
+ if len(types) == 1:
147
+ variable_type = list(types)[0]
148
+ else:
149
+ # This logic may be treated by the typeset
150
+ if (
151
+ types == {"Numeric", "Categorical"}
152
+ or types == {"Categorical", "Unsupported"}
153
+ or types == {"Categorical", "Text"}
154
+ ):
155
+ # Treating numeric as categorical, if one is unsupported, still render as categorical
156
+ variable_type = "Categorical"
157
+ else:
158
+ raise ValueError(f"Types for {idx} are not compatible: {types}")
159
+ else:
160
+ variable_type = summary["type"]
161
+ render_map_type = render_map.get(variable_type, render_map["Unsupported"])
162
+ template_variables.update(render_map_type(config, template_variables))
163
+
164
+ # Ignore these
165
+ if reject_variables:
166
+ ignore = AlertType.REJECTED in alert_types
167
+ else:
168
+ ignore = False
169
+
170
+ bottom = None
171
+ if "bottom" in template_variables and template_variables["bottom"] is not None:
172
+ btn = ToggleButton("More details", anchor_id=template_variables["varid"])
173
+ bottom = Collapse(btn, template_variables["bottom"])
174
+
175
+ var = Variable(
176
+ template_variables["top"],
177
+ bottom=bottom,
178
+ anchor_id=template_variables["varid"],
179
+ name=idx,
180
+ ignore=ignore,
181
+ )
182
+
183
+ templs.append(var)
184
+
185
+ return templs
186
+
187
+
188
+ def get_duplicates_items(
189
+ config: Settings, duplicates: pd.DataFrame
190
+ ) -> List[Renderable]:
191
+ """Create the list of duplicates items
192
+
193
+ Args:
194
+ config: settings object
195
+ duplicates: DataFrame of duplicates
196
+
197
+ Returns:
198
+ List of duplicates items to show in the interface.
199
+ """
200
+ items: List[Renderable] = []
201
+ if duplicates is not None and len(duplicates) > 0:
202
+ if isinstance(duplicates, list):
203
+ generator = (d is None for d in duplicates)
204
+ if any(generator):
205
+ return items
206
+
207
+ for idx, df in enumerate(duplicates):
208
+ items.append(
209
+ Duplicate(
210
+ duplicate=df,
211
+ name=config.html.style._labels[idx],
212
+ anchor_id="duplicates",
213
+ )
214
+ )
215
+ else:
216
+ items.append(
217
+ Duplicate(
218
+ duplicate=duplicates,
219
+ name="Most frequently occurring",
220
+ anchor_id="duplicates",
221
+ )
222
+ )
223
+ return items
224
+
225
+
226
+ def get_definition_items(definitions: pd.DataFrame) -> Sequence[Renderable]:
227
+ """Create the list of duplicates items
228
+
229
+ Args:
230
+ definitions: DataFrame of column definitions
231
+
232
+ Returns:
233
+ List of column definitions to show in the interface.
234
+ """
235
+ items = []
236
+ if definitions is not None and len(definitions) > 0:
237
+ items.append(
238
+ Duplicate(
239
+ duplicate=definitions,
240
+ name="Columns",
241
+ anchor_id="definitions",
242
+ )
243
+ )
244
+ return items
245
+
246
+
247
+ def get_sample_items(config: Settings, sample: dict) -> List[Renderable]:
248
+ """Create the list of sample items
249
+
250
+ Args:
251
+ config: settings object
252
+ sample: dict of samples
253
+
254
+ Returns:
255
+ List of sample items to show in the interface.
256
+ """
257
+ items: List[Renderable] = []
258
+ if isinstance(sample, tuple):
259
+ for s in zip(*sample):
260
+ items.append(
261
+ Container(
262
+ [
263
+ Sample(
264
+ sample=obj.data,
265
+ name=config.html.style._labels[idx],
266
+ anchor_id=obj.id,
267
+ caption=obj.caption,
268
+ )
269
+ for idx, obj in enumerate(s)
270
+ ],
271
+ sequence_type="batch_grid",
272
+ batch_size=len(sample),
273
+ anchor_id=f"sample_{slugify(s[0].name)}",
274
+ name=s[0].name,
275
+ )
276
+ )
277
+ else:
278
+ for obj in sample:
279
+ items.append(
280
+ Sample(
281
+ sample=obj.data,
282
+ name=obj.name,
283
+ anchor_id=obj.id,
284
+ caption=obj.caption,
285
+ )
286
+ )
287
+ return items
288
+
289
+
290
+ def get_interactions(config: Settings, interactions: dict) -> list:
291
+ """Returns the interaction components for the report
292
+
293
+ Args:
294
+ config: report Settings object
295
+ interactions: a nested dict containing the scatter plots
296
+
297
+ Returns:
298
+ A list of components for the interaction section of the report
299
+ """
300
+ titems: List[Renderable] = []
301
+
302
+ for x_col, y_cols in interactions.items():
303
+ items: List[Renderable] = []
304
+ for y_col, splot in y_cols.items():
305
+ if not isinstance(splot, list):
306
+ items.append(
307
+ ImageWidget(
308
+ splot,
309
+ image_format=config.plot.image_format,
310
+ alt=f"{x_col} x {y_col}",
311
+ anchor_id=f"interactions_{slugify(x_col)}_{slugify(y_col)}",
312
+ name=y_col,
313
+ )
314
+ )
315
+ else:
316
+ items.append(
317
+ Container(
318
+ [
319
+ ImageWidget(
320
+ zplot,
321
+ image_format=config.plot.image_format,
322
+ alt=f"{x_col} x {y_col}",
323
+ anchor_id=f"interactions_{slugify(x_col)}_{slugify(y_col)}",
324
+ name=config.html.style._labels[idx],
325
+ )
326
+ if zplot != ""
327
+ else HTML(
328
+ f"<h4 class='indent'>{config.html.style._labels[idx]}</h4><br />"
329
+ f"<em>Interaction plot not present for dataset</em>"
330
+ )
331
+ for idx, zplot in enumerate(splot)
332
+ ],
333
+ sequence_type="batch_grid",
334
+ batch_size=len(config.html.style._labels),
335
+ anchor_id=f"interactions_{slugify(x_col)}_{slugify(y_col)}",
336
+ name=y_col,
337
+ )
338
+ )
339
+
340
+ titems.append(
341
+ Container(
342
+ items,
343
+ sequence_type="tabs" if len(items) <= 10 else "select",
344
+ name=x_col,
345
+ nested=len(interactions) > 10,
346
+ anchor_id=f"interactions_{slugify(x_col)}",
347
+ )
348
+ )
349
+ return titems
350
+
351
+
352
+ def get_report_structure(config: Settings, summary: BaseDescription) -> Root:
353
+ """Generate a HTML report from summary statistics and a given sample.
354
+
355
+ Args:
356
+ config: report Settings object
357
+ summary: Statistics to use for the overview, variables, correlations and missing values.
358
+
359
+ Returns:
360
+ The profile report in HTML format
361
+ """
362
+ disable_progress_bar = not config.progress_bar
363
+ with tqdm(
364
+ total=1, desc="Generate report structure", disable=disable_progress_bar
365
+ ) as pbar:
366
+ alerts = summary.alerts
367
+
368
+ section_items: List[Renderable] = [
369
+ Container(
370
+ get_dataset_items(config, summary, alerts),
371
+ sequence_type="overview_tabs",
372
+ name="Overview",
373
+ anchor_id="overview",
374
+ oss=not bool(os.getenv("YDATA_SUPPRESS_BANNER", "")),
375
+ ),
376
+ ]
377
+
378
+ if len(summary.variables) > 0:
379
+ section_items.append(
380
+ Dropdown(
381
+ name="Variables",
382
+ anchor_id="variables-dropdown",
383
+ id="variables-dropdown",
384
+ is_row=False,
385
+ classes=["form-select"],
386
+ items=list(summary.variables),
387
+ item=Container(
388
+ render_variables_section(config, summary),
389
+ sequence_type="accordion",
390
+ name="Variables",
391
+ anchor_id="variables",
392
+ ),
393
+ )
394
+ )
395
+
396
+ scatter_items = get_interactions(config, summary.scatter)
397
+ if len(scatter_items) > 0:
398
+ section_items.append(
399
+ Container(
400
+ scatter_items,
401
+ sequence_type="tabs" if len(scatter_items) <= 10 else "select",
402
+ name="Interactions",
403
+ anchor_id="interactions",
404
+ ),
405
+ )
406
+
407
+ corr = get_correlation_items(config, summary)
408
+ if corr is not None:
409
+ section_items.append(corr)
410
+
411
+ missing_items = get_missing_items(config, summary)
412
+ if len(missing_items) > 0:
413
+ section_items.append(
414
+ Container(
415
+ missing_items,
416
+ sequence_type="tabs",
417
+ name="Missing values",
418
+ anchor_id="missing",
419
+ )
420
+ )
421
+
422
+ sample_items = get_sample_items(config, summary.sample)
423
+ if len(sample_items) > 0:
424
+ section_items.append(
425
+ Container(
426
+ items=sample_items,
427
+ sequence_type="tabs",
428
+ name="Sample",
429
+ anchor_id="sample",
430
+ )
431
+ )
432
+
433
+ duplicate_items = get_duplicates_items(config, summary.duplicates)
434
+ if len(duplicate_items) > 0:
435
+ section_items.append(
436
+ Container(
437
+ items=duplicate_items,
438
+ sequence_type="batch_grid",
439
+ batch_size=len(duplicate_items),
440
+ name="Duplicate rows",
441
+ anchor_id="duplicate",
442
+ )
443
+ )
444
+
445
+ sections = Container(
446
+ section_items,
447
+ name="Root",
448
+ sequence_type="sections",
449
+ full_width=config.html.full_width,
450
+ )
451
+ pbar.update()
452
+
453
+ footer = HTML(
454
+ content='Report generated by <a href="https://ydata.ai/?utm_source=opensource&utm_medium=pandasprofiling&utm_campaign=report">YData</a>.'
455
+ )
456
+
457
+ return Root("Root", sections, footer, style=config.html.style)
@@ -0,0 +1,35 @@
1
+ from data_profiling.report.structure.variables.render_boolean import render_boolean
2
+ from data_profiling.report.structure.variables.render_categorical import (
3
+ render_categorical,
4
+ )
5
+ from data_profiling.report.structure.variables.render_common import render_common
6
+ from data_profiling.report.structure.variables.render_complex import render_complex
7
+ from data_profiling.report.structure.variables.render_count import render_count
8
+ from data_profiling.report.structure.variables.render_date import render_date
9
+ from data_profiling.report.structure.variables.render_file import render_file
10
+ from data_profiling.report.structure.variables.render_generic import render_generic
11
+ from data_profiling.report.structure.variables.render_image import render_image
12
+ from data_profiling.report.structure.variables.render_path import render_path
13
+ from data_profiling.report.structure.variables.render_real import render_real
14
+ from data_profiling.report.structure.variables.render_text import render_text
15
+ from data_profiling.report.structure.variables.render_timeseries import (
16
+ render_timeseries,
17
+ )
18
+ from data_profiling.report.structure.variables.render_url import render_url
19
+
20
+ __all__ = [
21
+ "render_boolean",
22
+ "render_categorical",
23
+ "render_common",
24
+ "render_complex",
25
+ "render_count",
26
+ "render_date",
27
+ "render_file",
28
+ "render_generic",
29
+ "render_image",
30
+ "render_path",
31
+ "render_real",
32
+ "render_text",
33
+ "render_timeseries",
34
+ "render_url",
35
+ ]
@@ -0,0 +1,132 @@
1
+ from typing import 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
+ FrequencyTableSmall,
9
+ Image,
10
+ Table,
11
+ VariableInfo,
12
+ )
13
+ from data_profiling.report.presentation.core.renderable import Renderable
14
+ from data_profiling.report.presentation.frequency_table_utils import freq_table
15
+ from data_profiling.report.structure.variables.render_common import render_common
16
+ from data_profiling.visualisation.plot import cat_frequency_plot
17
+
18
+
19
+ def render_boolean(config: Settings, summary: dict) -> dict:
20
+ varid = summary["varid"]
21
+ n_obs_bool = config.vars.bool.n_obs
22
+ image_format = config.plot.image_format
23
+
24
+ # Prepare variables
25
+ template_variables = render_common(config, summary)
26
+
27
+ # Element composition
28
+ info = VariableInfo(
29
+ anchor_id=summary["varid"],
30
+ alerts=summary["alerts"],
31
+ var_type="Boolean",
32
+ var_name=summary["varname"],
33
+ description=summary["description"],
34
+ style=config.html.style,
35
+ )
36
+
37
+ table = 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": "Memory size",
61
+ "value": fmt_bytesize(summary["memory_size"]),
62
+ "alert": False,
63
+ },
64
+ ],
65
+ style=config.html.style,
66
+ )
67
+
68
+ fqm = FrequencyTableSmall(
69
+ freq_table(
70
+ freqtable=summary["value_counts_without_nan"],
71
+ n=summary["n"],
72
+ max_number_to_print=n_obs_bool,
73
+ ),
74
+ redact=False,
75
+ )
76
+
77
+ template_variables["top"] = Container([info, table, fqm], sequence_type="grid")
78
+
79
+ items: List[Renderable] = [
80
+ FrequencyTable(
81
+ template_variables["freq_table_rows"],
82
+ name="Common Values (Table)",
83
+ anchor_id=f"{varid}frequency_table",
84
+ redact=False,
85
+ )
86
+ ]
87
+
88
+ show = config.plot.cat_freq.show
89
+ max_unique = config.plot.cat_freq.max_unique
90
+
91
+ if show and (max_unique > 0):
92
+ if isinstance(summary["value_counts_without_nan"], list):
93
+ items.append(
94
+ Container(
95
+ [
96
+ Image(
97
+ cat_frequency_plot(
98
+ config,
99
+ s,
100
+ ),
101
+ image_format=image_format,
102
+ alt=config.html.style._labels[idx],
103
+ name=config.html.style._labels[idx],
104
+ anchor_id=f"{varid}cat_frequency_plot_{idx}",
105
+ )
106
+ for idx, s in enumerate(summary["value_counts_without_nan"])
107
+ ],
108
+ anchor_id=f"{varid}cat_frequency_plot",
109
+ name="Common Values (Plot)",
110
+ sequence_type="batch_grid",
111
+ batch_size=len(config.html.style._labels),
112
+ )
113
+ )
114
+ else:
115
+ items.append(
116
+ Image(
117
+ cat_frequency_plot(
118
+ config,
119
+ summary["value_counts_without_nan"],
120
+ ),
121
+ image_format=image_format,
122
+ alt="Common Values (Plot)",
123
+ name="Common Values (Plot)",
124
+ anchor_id=f"{varid}cat_frequency_plot",
125
+ )
126
+ )
127
+
128
+ template_variables["bottom"] = Container(
129
+ items, sequence_type="tabs", anchor_id=f"{varid}bottom"
130
+ )
131
+
132
+ return template_variables