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,371 @@
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
+ fmt_timespan_timedelta,
9
+ )
10
+ from data_profiling.report.presentation.core import (
11
+ Container,
12
+ FrequencyTable,
13
+ Image,
14
+ Table,
15
+ VariableInfo,
16
+ )
17
+ from data_profiling.report.structure.variables.render_common import render_common
18
+ from data_profiling.report.utils import image_or_empty
19
+ from data_profiling.visualisation.plot import (
20
+ histogram,
21
+ mini_ts_plot,
22
+ plot_acf_pacf,
23
+ plot_timeseries_gap_analysis,
24
+ )
25
+
26
+
27
+ def _render_gap_tab(config: Settings, summary: dict) -> Container:
28
+ gap_stats = [
29
+ {
30
+ "name": "number of gaps",
31
+ "value": fmt_numeric(
32
+ summary["gap_stats"]["n_gaps"], precision=config.report.precision
33
+ ),
34
+ },
35
+ {
36
+ "name": "min",
37
+ "value": fmt_timespan_timedelta(
38
+ summary["gap_stats"]["min"], precision=config.report.precision
39
+ ),
40
+ },
41
+ {
42
+ "name": "max",
43
+ "value": fmt_timespan_timedelta(
44
+ summary["gap_stats"]["max"], precision=config.report.precision
45
+ ),
46
+ },
47
+ {
48
+ "name": "mean",
49
+ "value": fmt_timespan_timedelta(
50
+ summary["gap_stats"]["mean"], precision=config.report.precision
51
+ ),
52
+ },
53
+ {
54
+ "name": "std",
55
+ "value": fmt_timespan_timedelta(
56
+ summary["gap_stats"]["std"], precision=config.report.precision
57
+ ),
58
+ },
59
+ ]
60
+
61
+ gap_table = Table(
62
+ gap_stats,
63
+ name="Gap statistics",
64
+ style=config.html.style,
65
+ )
66
+
67
+ gap_plot = Image(
68
+ plot_timeseries_gap_analysis(
69
+ config, summary["gap_stats"]["series"], summary["gap_stats"]["gaps"]
70
+ ),
71
+ image_format=config.plot.image_format,
72
+ alt="Gap plot",
73
+ name="",
74
+ anchor_id=f"{summary['varid']}_gap_plot",
75
+ )
76
+ return Container(
77
+ [gap_table, gap_plot],
78
+ image_format=config.plot.image_format,
79
+ sequence_type="grid",
80
+ name="Gap analysis",
81
+ anchor_id=f"{summary['varid']}_gap_analysis",
82
+ )
83
+
84
+
85
+ def render_timeseries(config: Settings, summary: dict) -> dict:
86
+ varid = summary["varid"]
87
+ template_variables = render_common(config, summary)
88
+ image_format = config.plot.image_format
89
+ name = "Numeric time series"
90
+
91
+ # Top
92
+ info = VariableInfo(
93
+ summary["varid"],
94
+ summary["varname"],
95
+ name,
96
+ summary["alerts"],
97
+ summary["description"],
98
+ style=config.html.style,
99
+ )
100
+
101
+ table1 = Table(
102
+ [
103
+ {
104
+ "name": "Distinct",
105
+ "value": fmt(summary["n_distinct"]),
106
+ "alert": "n_distinct" in summary["alert_fields"],
107
+ },
108
+ {
109
+ "name": "Distinct (%)",
110
+ "value": fmt_percent(summary["p_distinct"]),
111
+ "alert": "p_distinct" in summary["alert_fields"],
112
+ },
113
+ {
114
+ "name": "Missing",
115
+ "value": fmt(summary["n_missing"]),
116
+ "alert": "n_missing" in summary["alert_fields"],
117
+ },
118
+ {
119
+ "name": "Missing (%)",
120
+ "value": fmt_percent(summary["p_missing"]),
121
+ "alert": "p_missing" in summary["alert_fields"],
122
+ },
123
+ {
124
+ "name": "Infinite",
125
+ "value": fmt(summary["n_infinite"]),
126
+ "alert": "n_infinite" in summary["alert_fields"],
127
+ },
128
+ {
129
+ "name": "Infinite (%)",
130
+ "value": fmt_percent(summary["p_infinite"]),
131
+ "alert": "p_infinite" in summary["alert_fields"],
132
+ },
133
+ ],
134
+ style=config.html.style,
135
+ )
136
+
137
+ table2 = Table(
138
+ [
139
+ {
140
+ "name": "Mean",
141
+ "value": fmt_numeric(
142
+ summary["mean"], precision=config.report.precision
143
+ ),
144
+ "alert": False,
145
+ },
146
+ {
147
+ "name": "Minimum",
148
+ "value": fmt_numeric(summary["min"], precision=config.report.precision),
149
+ "alert": False,
150
+ },
151
+ {
152
+ "name": "Maximum",
153
+ "value": fmt_numeric(summary["max"], precision=config.report.precision),
154
+ "alert": False,
155
+ },
156
+ {
157
+ "name": "Zeros",
158
+ "value": fmt(summary["n_zeros"]),
159
+ "alert": "n_zeros" in summary["alert_fields"],
160
+ },
161
+ {
162
+ "name": "Zeros (%)",
163
+ "value": fmt_percent(summary["p_zeros"]),
164
+ "alert": "p_zeros" in summary["alert_fields"],
165
+ },
166
+ {
167
+ "name": "Memory size",
168
+ "value": fmt_bytesize(summary["memory_size"]),
169
+ "alert": False,
170
+ },
171
+ ],
172
+ style=config.html.style,
173
+ )
174
+
175
+ mini_plot = Image(
176
+ mini_ts_plot(config, summary["series"]),
177
+ image_format=image_format,
178
+ alt="Mini TS plot",
179
+ )
180
+
181
+ template_variables["top"] = Container(
182
+ [info, table1, table2, mini_plot], sequence_type="grid"
183
+ )
184
+
185
+ quantile_statistics = Table(
186
+ [
187
+ {
188
+ "name": "Minimum",
189
+ "value": fmt_numeric(summary["min"], precision=config.report.precision),
190
+ },
191
+ {
192
+ "name": "5-th percentile",
193
+ "value": fmt_numeric(summary["5%"], precision=config.report.precision),
194
+ },
195
+ {
196
+ "name": "Q1",
197
+ "value": fmt_numeric(summary["25%"], precision=config.report.precision),
198
+ },
199
+ {
200
+ "name": "median",
201
+ "value": fmt_numeric(summary["50%"], precision=config.report.precision),
202
+ },
203
+ {
204
+ "name": "Q3",
205
+ "value": fmt_numeric(summary["75%"], precision=config.report.precision),
206
+ },
207
+ {
208
+ "name": "95-th percentile",
209
+ "value": fmt_numeric(summary["95%"], precision=config.report.precision),
210
+ },
211
+ {
212
+ "name": "Maximum",
213
+ "value": fmt_numeric(summary["max"], precision=config.report.precision),
214
+ },
215
+ {
216
+ "name": "Range",
217
+ "value": fmt_numeric(
218
+ summary["range"], precision=config.report.precision
219
+ ),
220
+ },
221
+ {
222
+ "name": "Interquartile range (IQR)",
223
+ "value": fmt_numeric(summary["iqr"], precision=config.report.precision),
224
+ },
225
+ ],
226
+ name="Quantile statistics",
227
+ style=config.html.style,
228
+ )
229
+
230
+ descriptive_statistics = Table(
231
+ [
232
+ {
233
+ "name": "Standard deviation",
234
+ "value": fmt_numeric(summary["std"], precision=config.report.precision),
235
+ },
236
+ {
237
+ "name": "Coefficient of variation (CV)",
238
+ "value": fmt_numeric(summary["cv"], precision=config.report.precision),
239
+ },
240
+ {
241
+ "name": "Kurtosis",
242
+ "value": fmt_numeric(
243
+ summary["kurtosis"], precision=config.report.precision
244
+ ),
245
+ },
246
+ {
247
+ "name": "Mean",
248
+ "value": fmt_numeric(
249
+ summary["mean"], precision=config.report.precision
250
+ ),
251
+ },
252
+ {
253
+ "name": "Median Absolute Deviation (MAD)",
254
+ "value": fmt_numeric(summary["mad"], precision=config.report.precision),
255
+ },
256
+ {
257
+ "name": "Skewness",
258
+ "value": fmt_numeric(
259
+ summary["skewness"], precision=config.report.precision
260
+ ),
261
+ "class": "alert" if "skewness" in summary["alert_fields"] else "",
262
+ },
263
+ {
264
+ "name": "Sum",
265
+ "value": fmt_numeric(summary["sum"], precision=config.report.precision),
266
+ },
267
+ {
268
+ "name": "Variance",
269
+ "value": fmt_numeric(
270
+ summary["variance"], precision=config.report.precision
271
+ ),
272
+ },
273
+ {
274
+ "name": "Monotonicity",
275
+ "value": fmt_monotonic(summary["monotonic"]),
276
+ },
277
+ {
278
+ "name": "Augmented Dickey-Fuller test p-value",
279
+ "value": fmt_numeric(summary["addfuller"]),
280
+ },
281
+ ],
282
+ name="Descriptive statistics",
283
+ style=config.html.style,
284
+ )
285
+
286
+ statistics = Container(
287
+ [quantile_statistics, descriptive_statistics],
288
+ anchor_id=f"{varid}statistics",
289
+ name="Statistics",
290
+ sequence_type="grid",
291
+ )
292
+
293
+ summary_histogram = summary.get("histogram", [])
294
+
295
+ hist_data = None
296
+ hist_caption = None
297
+
298
+ if summary_histogram:
299
+ if isinstance(summary_histogram, list):
300
+ hist_data = histogram(
301
+ config,
302
+ [x[0] for x in summary["histogram"]],
303
+ [x[1] for x in summary["histogram"]],
304
+ )
305
+ hist_caption = f"<strong>Histogram with fixed size bins</strong> (bins={len(summary['histogram'][0][1]) - 1})"
306
+ else:
307
+ hist_data = histogram(config, *summary["histogram"])
308
+ hist_caption = f"<strong>Histogram with fixed size bins</strong> (bins={len(summary['histogram'][1]) - 1})"
309
+
310
+ hist = image_or_empty(
311
+ hist_data,
312
+ image_format=image_format,
313
+ alt="Histogram",
314
+ caption=hist_caption,
315
+ name="Histogram",
316
+ anchor_id=f"{varid}histogram",
317
+ )
318
+
319
+ fq = FrequencyTable(
320
+ template_variables["freq_table_rows"],
321
+ name="Common values",
322
+ anchor_id=f"{varid}common_values",
323
+ redact=False,
324
+ )
325
+
326
+ evs = Container(
327
+ [
328
+ FrequencyTable(
329
+ template_variables["firstn_expanded"],
330
+ name=f"Minimum {config.n_extreme_obs} values",
331
+ anchor_id=f"{varid}firstn",
332
+ redact=False,
333
+ ),
334
+ FrequencyTable(
335
+ template_variables["lastn_expanded"],
336
+ name=f"Maximum {config.n_extreme_obs} values",
337
+ anchor_id=f"{varid}lastn",
338
+ redact=False,
339
+ ),
340
+ ],
341
+ sequence_type="tabs",
342
+ name="Extreme values",
343
+ anchor_id=f"{varid}extreme_values",
344
+ )
345
+
346
+ acf_pacf = Image(
347
+ plot_acf_pacf(config, summary["series"]),
348
+ image_format=image_format,
349
+ alt="Autocorrelation",
350
+ caption="<strong>ACF and PACF</strong>",
351
+ name="Autocorrelation",
352
+ anchor_id=f"{varid}acf_pacf",
353
+ )
354
+
355
+ ts_plot = Image(
356
+ mini_ts_plot(config, summary["series"], figsize=(7, 3)),
357
+ image_format=image_format,
358
+ alt="Time-series plot",
359
+ name="Time-series",
360
+ anchor_id=f"{varid}_ts_plot",
361
+ )
362
+
363
+ ts_gap = _render_gap_tab(config, summary)
364
+
365
+ template_variables["bottom"] = Container(
366
+ [statistics, hist, ts_plot, ts_gap, fq, evs, acf_pacf],
367
+ sequence_type="tabs",
368
+ anchor_id=f"{varid}bottom",
369
+ )
370
+
371
+ return template_variables
@@ -0,0 +1,132 @@
1
+ from data_profiling.config import Settings
2
+ from data_profiling.report.formatters import fmt, fmt_bytesize, fmt_percent
3
+ from data_profiling.report.presentation.core import (
4
+ Container,
5
+ FrequencyTable,
6
+ FrequencyTableSmall,
7
+ Table,
8
+ VariableInfo,
9
+ )
10
+ from data_profiling.report.presentation.frequency_table_utils import freq_table
11
+ from data_profiling.report.structure.variables.render_common import render_common
12
+
13
+
14
+ def render_url(config: Settings, summary: dict) -> dict:
15
+ varid = summary["varid"]
16
+ n_freq_table_max = config.n_freq_table_max
17
+
18
+ n_obs_cat = config.vars.cat.n_obs
19
+ redact = config.vars.cat.redact
20
+
21
+ template_variables = render_common(config, summary)
22
+
23
+ keys = ["scheme", "netloc", "path", "query", "fragment"]
24
+ for url_part in keys:
25
+ template_variables[f"freqtable_{url_part}"] = freq_table(
26
+ freqtable=summary[f"{url_part}_counts"],
27
+ n=summary["n"],
28
+ max_number_to_print=n_freq_table_max,
29
+ )
30
+
31
+ full_frequency_table = FrequencyTable(
32
+ template_variables["freq_table_rows"],
33
+ name="Full",
34
+ anchor_id=f"{varid}full_frequency",
35
+ redact=redact,
36
+ )
37
+ scheme_frequency_table = FrequencyTable(
38
+ template_variables["freqtable_scheme"],
39
+ name="Scheme",
40
+ anchor_id=f"{varid}scheme_frequency",
41
+ redact=redact,
42
+ )
43
+ netloc_frequency_table = FrequencyTable(
44
+ template_variables["freqtable_netloc"],
45
+ name="Netloc",
46
+ anchor_id=f"{varid}netloc_frequency",
47
+ redact=redact,
48
+ )
49
+ path_frequency_table = FrequencyTable(
50
+ template_variables["freqtable_path"],
51
+ name="Path",
52
+ anchor_id=f"{varid}path_frequency",
53
+ redact=redact,
54
+ )
55
+ query_frequency_table = FrequencyTable(
56
+ template_variables["freqtable_query"],
57
+ name="Query",
58
+ anchor_id=f"{varid}query_frequency",
59
+ redact=redact,
60
+ )
61
+ fragment_frequency_table = FrequencyTable(
62
+ template_variables["freqtable_fragment"],
63
+ name="Fragment",
64
+ anchor_id=f"{varid}fragment_frequency",
65
+ redact=redact,
66
+ )
67
+
68
+ items = [
69
+ full_frequency_table,
70
+ scheme_frequency_table,
71
+ netloc_frequency_table,
72
+ path_frequency_table,
73
+ query_frequency_table,
74
+ fragment_frequency_table,
75
+ ]
76
+ template_variables["bottom"] = Container(
77
+ items, sequence_type="tabs", name="url stats", anchor_id=f"{varid}urlstats"
78
+ )
79
+
80
+ # Element composition
81
+ info = VariableInfo(
82
+ summary["varid"],
83
+ summary["varname"],
84
+ "URL",
85
+ summary["alerts"],
86
+ summary["description"],
87
+ style=config.html.style,
88
+ )
89
+
90
+ table = Table(
91
+ [
92
+ {
93
+ "name": "Distinct",
94
+ "value": fmt(summary["n_distinct"]),
95
+ "alert": "n_distinct" in summary["alert_fields"],
96
+ },
97
+ {
98
+ "name": "Distinct (%)",
99
+ "value": fmt_percent(summary["p_distinct"]),
100
+ "alert": "p_distinct" in summary["alert_fields"],
101
+ },
102
+ {
103
+ "name": "Missing",
104
+ "value": fmt(summary["n_missing"]),
105
+ "alert": "n_missing" in summary["alert_fields"],
106
+ },
107
+ {
108
+ "name": "Missing (%)",
109
+ "value": fmt_percent(summary["p_missing"]),
110
+ "alert": "p_missing" in summary["alert_fields"],
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
+ fqm = FrequencyTableSmall(
122
+ freq_table(
123
+ freqtable=summary["value_counts_without_nan"],
124
+ n=summary["n"],
125
+ max_number_to_print=n_obs_cat,
126
+ ),
127
+ redact=redact,
128
+ )
129
+
130
+ template_variables["top"] = Container([info, table, fqm], sequence_type="grid")
131
+
132
+ return template_variables
@@ -0,0 +1,34 @@
1
+ from typing import Optional
2
+
3
+ from data_profiling.config import ImageType
4
+ from data_profiling.report.presentation.core import Container, Image
5
+
6
+
7
+ def image_or_empty(
8
+ image: Optional[str],
9
+ *,
10
+ alt: str,
11
+ image_format: ImageType,
12
+ caption: Optional[str] = None,
13
+ name: Optional[str] = None,
14
+ anchor_id: Optional[str] = None,
15
+ ) -> Container | Image:
16
+ """
17
+ Add helper to render an image or an empty container when necessary.
18
+ """
19
+ if image is None:
20
+ return Container(
21
+ items=[],
22
+ name=name or f"{alt}_empty",
23
+ anchor_id=anchor_id,
24
+ sequence_type="grid",
25
+ )
26
+
27
+ return Image(
28
+ image=image,
29
+ image_format=image_format,
30
+ alt=alt,
31
+ caption=caption,
32
+ name=name,
33
+ anchor_id=anchor_id,
34
+ )
@@ -0,0 +1,143 @@
1
+ import warnings
2
+ from pathlib import Path
3
+ from typing import TYPE_CHECKING, Optional, Union
4
+
5
+ if TYPE_CHECKING:
6
+ from data_profiling.profile_report import ProfileReport
7
+
8
+ from data_profiling.config import Settings
9
+ from data_profiling.model import BaseDescription
10
+ from data_profiling.report.presentation.core import Root
11
+ from data_profiling.version import __version__
12
+
13
+
14
+ class SerializeReport:
15
+ """Extend the report to be able to dump and load reports."""
16
+
17
+ df = None
18
+ config = None
19
+ _df_hash: Optional[str] = None
20
+ _report = None
21
+ _description_set = None
22
+
23
+ @property
24
+ def df_hash(self) -> Optional[str]:
25
+ return None
26
+
27
+ def dumps(self) -> bytes:
28
+ """
29
+ Serialize ProfileReport and return bytes for reproducing ProfileReport or Caching.
30
+
31
+ Returns:
32
+ Bytes which contains hash of DataFrame, config, _description_set and _report
33
+ """
34
+ import pickle
35
+
36
+ # Note: _description_set and _report may are None if they haven't been computed
37
+ return pickle.dumps(
38
+ [
39
+ self.df_hash,
40
+ self.config,
41
+ self._description_set,
42
+ self._report,
43
+ ]
44
+ )
45
+
46
+ def loads(self, data: bytes) -> Union["ProfileReport", "SerializeReport"]:
47
+ """
48
+ Deserialize the serialized report
49
+
50
+ Args:
51
+ data: The bytes of a serialize ProfileReport object.
52
+
53
+ Raises:
54
+ ValueError: if ignore_config is set to False and the configs do not match.
55
+
56
+ Returns:
57
+ self
58
+ """
59
+ import pickle
60
+
61
+ try:
62
+ (
63
+ df_hash,
64
+ loaded_config,
65
+ loaded_description_set,
66
+ loaded_report,
67
+ ) = pickle.loads(data)
68
+ except Exception as e:
69
+ raise ValueError("Failed to load data") from e
70
+
71
+ if not all(
72
+ (
73
+ df_hash is None or isinstance(df_hash, str),
74
+ isinstance(loaded_config, Settings),
75
+ loaded_description_set is None
76
+ or isinstance(loaded_description_set, BaseDescription),
77
+ loaded_report is None or isinstance(loaded_report, Root),
78
+ )
79
+ ):
80
+ raise ValueError(
81
+ "Failed to load data: file may be damaged or from an incompatible version"
82
+ )
83
+ if (df_hash == self.df_hash) or (self.df is None):
84
+ # load to an empty ProfileReport
85
+ # Set description_set, report, sample if they are None,or raise an warning.
86
+ if self._description_set is None:
87
+ self._description_set = loaded_description_set
88
+ else:
89
+ warnings.warn(
90
+ "The description set of current ProfileReport is not None. It won't be loaded."
91
+ )
92
+ if self._report is None:
93
+ self._report = loaded_report
94
+ else:
95
+ warnings.warn(
96
+ "The report of current ProfileReport is not None. It won't be loaded."
97
+ )
98
+
99
+ # overwrite config
100
+ self.config = loaded_config
101
+
102
+ # warn if version not equal
103
+ if (
104
+ loaded_description_set is not None
105
+ and loaded_description_set.package["data_profiling_version"]
106
+ != __version__
107
+ ):
108
+ warnings.warn(
109
+ f"The package version specified in the loaded data is not equal to the version installed. "
110
+ f"Currently running on data-profiling {__version__} , while loaded data is generated by data_profiling, {loaded_description_set.package['data_profiling_version']}."
111
+ )
112
+
113
+ # set df_hash
114
+ self._df_hash = df_hash
115
+
116
+ else:
117
+ raise ValueError("DataFrame does not match with the current ProfileReport.")
118
+ return self
119
+
120
+ def dump(self, output_file: Union[Path, str]) -> None:
121
+ """
122
+ Dump ProfileReport to file
123
+ """
124
+ if not isinstance(output_file, Path):
125
+ output_file = Path(str(output_file))
126
+
127
+ output_file = output_file.with_suffix(".pp")
128
+ output_file.write_bytes(self.dumps())
129
+
130
+ def load(
131
+ self, load_file: Union[Path, str]
132
+ ) -> Union["ProfileReport", "SerializeReport"]:
133
+ """
134
+ Load ProfileReport from file
135
+
136
+ Raises:
137
+ ValueError: if the DataFrame or Config do not match with the current ProfileReport
138
+ """
139
+ if not isinstance(load_file, Path):
140
+ load_file = Path(str(load_file))
141
+
142
+ self.loads(load_file.read_bytes())
143
+ return self
@@ -0,0 +1 @@
1
+ """Utility functions for the complete package."""
@@ -0,0 +1,9 @@
1
+ """
2
+ File with a function to check the backend being used
3
+ """
4
+ import importlib
5
+
6
+
7
+ def is_pyspark_installed() -> bool:
8
+ """Check if PySpark is installed without importing it."""
9
+ return importlib.util.find_spec("pyspark") is not None